diff options
Diffstat (limited to 'drivers/tty/serial')
84 files changed, 4289 insertions, 1064 deletions
diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index a44345a2dbb4..c7e8b60b6177 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c | |||
@@ -85,7 +85,6 @@ static void serial21285_enable_ms(struct uart_port *port) | |||
85 | static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) | 85 | static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) |
86 | { | 86 | { |
87 | struct uart_port *port = dev_id; | 87 | struct uart_port *port = dev_id; |
88 | struct tty_struct *tty = port->state->port.tty; | ||
89 | unsigned int status, ch, flag, rxs, max_count = 256; | 88 | unsigned int status, ch, flag, rxs, max_count = 256; |
90 | 89 | ||
91 | status = *CSR_UARTFLG; | 90 | status = *CSR_UARTFLG; |
@@ -115,7 +114,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) | |||
115 | 114 | ||
116 | status = *CSR_UARTFLG; | 115 | status = *CSR_UARTFLG; |
117 | } | 116 | } |
118 | tty_flip_buffer_push(tty); | 117 | tty_flip_buffer_push(&port->state->port); |
119 | 118 | ||
120 | return IRQ_HANDLED; | 119 | return IRQ_HANDLED; |
121 | } | 120 | } |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index f99a84526f82..49399470794d 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
@@ -262,8 +262,7 @@ static void rs_start(struct tty_struct *tty) | |||
262 | local_irq_restore(flags); | 262 | local_irq_restore(flags); |
263 | } | 263 | } |
264 | 264 | ||
265 | static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | 265 | static void receive_chars(struct m68k_serial *info, unsigned short rx) |
266 | unsigned short rx) | ||
267 | { | 266 | { |
268 | m68328_uart *uart = &uart_addr[info->line]; | 267 | m68328_uart *uart = &uart_addr[info->line]; |
269 | unsigned char ch, flag; | 268 | unsigned char ch, flag; |
@@ -293,9 +292,6 @@ static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | |||
293 | } | 292 | } |
294 | } | 293 | } |
295 | 294 | ||
296 | if(!tty) | ||
297 | goto clear_and_exit; | ||
298 | |||
299 | flag = TTY_NORMAL; | 295 | flag = TTY_NORMAL; |
300 | 296 | ||
301 | if (rx & URX_PARITY_ERROR) | 297 | if (rx & URX_PARITY_ERROR) |
@@ -305,15 +301,12 @@ static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | |||
305 | else if (rx & URX_FRAME_ERROR) | 301 | else if (rx & URX_FRAME_ERROR) |
306 | flag = TTY_FRAME; | 302 | flag = TTY_FRAME; |
307 | 303 | ||
308 | tty_insert_flip_char(tty, ch, flag); | 304 | tty_insert_flip_char(&info->tport, ch, flag); |
309 | #ifndef CONFIG_XCOPILOT_BUGS | 305 | #ifndef CONFIG_XCOPILOT_BUGS |
310 | } while((rx = uart->urx.w) & URX_DATA_READY); | 306 | } while((rx = uart->urx.w) & URX_DATA_READY); |
311 | #endif | 307 | #endif |
312 | 308 | ||
313 | tty_schedule_flip(tty); | 309 | tty_schedule_flip(&info->tport); |
314 | |||
315 | clear_and_exit: | ||
316 | return; | ||
317 | } | 310 | } |
318 | 311 | ||
319 | static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) | 312 | static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) |
@@ -367,11 +360,11 @@ irqreturn_t rs_interrupt(int irq, void *dev_id) | |||
367 | tx = uart->utx.w; | 360 | tx = uart->utx.w; |
368 | 361 | ||
369 | if (rx & URX_DATA_READY) | 362 | if (rx & URX_DATA_READY) |
370 | receive_chars(info, tty, rx); | 363 | receive_chars(info, rx); |
371 | if (tx & UTX_TX_AVAIL) | 364 | if (tx & UTX_TX_AVAIL) |
372 | transmit_chars(info, tty); | 365 | transmit_chars(info, tty); |
373 | #else | 366 | #else |
374 | receive_chars(info, tty, rx); | 367 | receive_chars(info, rx); |
375 | #endif | 368 | #endif |
376 | tty_kref_put(tty); | 369 | tty_kref_put(tty); |
377 | 370 | ||
@@ -1009,7 +1002,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1009 | m68328_uart *uart = &uart_addr[info->line]; | 1002 | m68328_uart *uart = &uart_addr[info->line]; |
1010 | unsigned long flags; | 1003 | unsigned long flags; |
1011 | 1004 | ||
1012 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) | 1005 | if (serial_paranoia_check(info, tty->name, "rs_close")) |
1013 | return; | 1006 | return; |
1014 | 1007 | ||
1015 | local_irq_save(flags); | 1008 | local_irq_save(flags); |
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index f9320437a649..0efc815a4968 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c | |||
@@ -239,13 +239,6 @@ static const struct serial8250_config uart_config[] = { | |||
239 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 239 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
240 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, | 240 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, |
241 | }, | 241 | }, |
242 | [PORT_RM9000] = { | ||
243 | .name = "RM9000", | ||
244 | .fifo_size = 16, | ||
245 | .tx_loadsz = 16, | ||
246 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | ||
247 | .flags = UART_CAP_FIFO, | ||
248 | }, | ||
249 | [PORT_OCTEON] = { | 242 | [PORT_OCTEON] = { |
250 | .name = "OCTEON", | 243 | .name = "OCTEON", |
251 | .fifo_size = 64, | 244 | .fifo_size = 64, |
@@ -324,9 +317,9 @@ static void default_serial_dl_write(struct uart_8250_port *up, int value) | |||
324 | serial_out(up, UART_DLM, value >> 8 & 0xff); | 317 | serial_out(up, UART_DLM, value >> 8 & 0xff); |
325 | } | 318 | } |
326 | 319 | ||
327 | #ifdef CONFIG_MIPS_ALCHEMY | 320 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) |
328 | 321 | ||
329 | /* Au1x00 UART hardware has a weird register layout */ | 322 | /* Au1x00/RT288x UART hardware has a weird register layout */ |
330 | static const u8 au_io_in_map[] = { | 323 | static const u8 au_io_in_map[] = { |
331 | [UART_RX] = 0, | 324 | [UART_RX] = 0, |
332 | [UART_IER] = 2, | 325 | [UART_IER] = 2, |
@@ -370,56 +363,6 @@ static void au_serial_dl_write(struct uart_8250_port *up, int value) | |||
370 | 363 | ||
371 | #endif | 364 | #endif |
372 | 365 | ||
373 | #ifdef CONFIG_SERIAL_8250_RM9K | ||
374 | |||
375 | static const u8 | ||
376 | regmap_in[8] = { | ||
377 | [UART_RX] = 0x00, | ||
378 | [UART_IER] = 0x0c, | ||
379 | [UART_IIR] = 0x14, | ||
380 | [UART_LCR] = 0x1c, | ||
381 | [UART_MCR] = 0x20, | ||
382 | [UART_LSR] = 0x24, | ||
383 | [UART_MSR] = 0x28, | ||
384 | [UART_SCR] = 0x2c | ||
385 | }, | ||
386 | regmap_out[8] = { | ||
387 | [UART_TX] = 0x04, | ||
388 | [UART_IER] = 0x0c, | ||
389 | [UART_FCR] = 0x18, | ||
390 | [UART_LCR] = 0x1c, | ||
391 | [UART_MCR] = 0x20, | ||
392 | [UART_LSR] = 0x24, | ||
393 | [UART_MSR] = 0x28, | ||
394 | [UART_SCR] = 0x2c | ||
395 | }; | ||
396 | |||
397 | static unsigned int rm9k_serial_in(struct uart_port *p, int offset) | ||
398 | { | ||
399 | offset = regmap_in[offset] << p->regshift; | ||
400 | return readl(p->membase + offset); | ||
401 | } | ||
402 | |||
403 | static void rm9k_serial_out(struct uart_port *p, int offset, int value) | ||
404 | { | ||
405 | offset = regmap_out[offset] << p->regshift; | ||
406 | writel(value, p->membase + offset); | ||
407 | } | ||
408 | |||
409 | static int rm9k_serial_dl_read(struct uart_8250_port *up) | ||
410 | { | ||
411 | return ((__raw_readl(up->port.membase + 0x10) << 8) | | ||
412 | (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff; | ||
413 | } | ||
414 | |||
415 | static void rm9k_serial_dl_write(struct uart_8250_port *up, int value) | ||
416 | { | ||
417 | __raw_writel(value, up->port.membase + 0x08); | ||
418 | __raw_writel(value >> 8, up->port.membase + 0x10); | ||
419 | } | ||
420 | |||
421 | #endif | ||
422 | |||
423 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) | 366 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) |
424 | { | 367 | { |
425 | offset = offset << p->regshift; | 368 | offset = offset << p->regshift; |
@@ -497,16 +440,7 @@ static void set_io_from_upio(struct uart_port *p) | |||
497 | p->serial_out = mem32_serial_out; | 440 | p->serial_out = mem32_serial_out; |
498 | break; | 441 | break; |
499 | 442 | ||
500 | #ifdef CONFIG_SERIAL_8250_RM9K | 443 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) |
501 | case UPIO_RM9000: | ||
502 | p->serial_in = rm9k_serial_in; | ||
503 | p->serial_out = rm9k_serial_out; | ||
504 | up->dl_read = rm9k_serial_dl_read; | ||
505 | up->dl_write = rm9k_serial_dl_write; | ||
506 | break; | ||
507 | #endif | ||
508 | |||
509 | #ifdef CONFIG_MIPS_ALCHEMY | ||
510 | case UPIO_AU: | 444 | case UPIO_AU: |
511 | p->serial_in = au_serial_in; | 445 | p->serial_in = au_serial_in; |
512 | p->serial_out = au_serial_out; | 446 | p->serial_out = au_serial_out; |
@@ -1341,7 +1275,9 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1341 | struct uart_8250_port *up = | 1275 | struct uart_8250_port *up = |
1342 | container_of(port, struct uart_8250_port, port); | 1276 | container_of(port, struct uart_8250_port, port); |
1343 | 1277 | ||
1344 | if (!(up->ier & UART_IER_THRI)) { | 1278 | if (up->dma && !serial8250_tx_dma(up)) { |
1279 | return; | ||
1280 | } else if (!(up->ier & UART_IER_THRI)) { | ||
1345 | up->ier |= UART_IER_THRI; | 1281 | up->ier |= UART_IER_THRI; |
1346 | serial_port_out(port, UART_IER, up->ier); | 1282 | serial_port_out(port, UART_IER, up->ier); |
1347 | 1283 | ||
@@ -1349,9 +1285,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1349 | unsigned char lsr; | 1285 | unsigned char lsr; |
1350 | lsr = serial_in(up, UART_LSR); | 1286 | lsr = serial_in(up, UART_LSR); |
1351 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1287 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1352 | if ((port->type == PORT_RM9000) ? | 1288 | if (lsr & UART_LSR_TEMT) |
1353 | (lsr & UART_LSR_THRE) : | ||
1354 | (lsr & UART_LSR_TEMT)) | ||
1355 | serial8250_tx_chars(up); | 1289 | serial8250_tx_chars(up); |
1356 | } | 1290 | } |
1357 | } | 1291 | } |
@@ -1397,7 +1331,6 @@ unsigned char | |||
1397 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | 1331 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) |
1398 | { | 1332 | { |
1399 | struct uart_port *port = &up->port; | 1333 | struct uart_port *port = &up->port; |
1400 | struct tty_struct *tty = port->state->port.tty; | ||
1401 | unsigned char ch; | 1334 | unsigned char ch; |
1402 | int max_count = 256; | 1335 | int max_count = 256; |
1403 | char flag; | 1336 | char flag; |
@@ -1462,7 +1395,7 @@ ignore_char: | |||
1462 | lsr = serial_in(up, UART_LSR); | 1395 | lsr = serial_in(up, UART_LSR); |
1463 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); | 1396 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); |
1464 | spin_unlock(&port->lock); | 1397 | spin_unlock(&port->lock); |
1465 | tty_flip_buffer_push(tty); | 1398 | tty_flip_buffer_push(&port->state->port); |
1466 | spin_lock(&port->lock); | 1399 | spin_lock(&port->lock); |
1467 | return lsr; | 1400 | return lsr; |
1468 | } | 1401 | } |
@@ -1547,6 +1480,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1547 | unsigned long flags; | 1480 | unsigned long flags; |
1548 | struct uart_8250_port *up = | 1481 | struct uart_8250_port *up = |
1549 | container_of(port, struct uart_8250_port, port); | 1482 | container_of(port, struct uart_8250_port, port); |
1483 | int dma_err = 0; | ||
1550 | 1484 | ||
1551 | if (iir & UART_IIR_NO_INT) | 1485 | if (iir & UART_IIR_NO_INT) |
1552 | return 0; | 1486 | return 0; |
@@ -1557,8 +1491,13 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1557 | 1491 | ||
1558 | DEBUG_INTR("status = %x...", status); | 1492 | DEBUG_INTR("status = %x...", status); |
1559 | 1493 | ||
1560 | if (status & (UART_LSR_DR | UART_LSR_BI)) | 1494 | if (status & (UART_LSR_DR | UART_LSR_BI)) { |
1561 | status = serial8250_rx_chars(up, status); | 1495 | if (up->dma) |
1496 | dma_err = serial8250_rx_dma(up, iir); | ||
1497 | |||
1498 | if (!up->dma || dma_err) | ||
1499 | status = serial8250_rx_chars(up, status); | ||
1500 | } | ||
1562 | serial8250_modem_status(up); | 1501 | serial8250_modem_status(up); |
1563 | if (status & UART_LSR_THRE) | 1502 | if (status & UART_LSR_THRE) |
1564 | serial8250_tx_chars(up); | 1503 | serial8250_tx_chars(up); |
@@ -1991,9 +1930,12 @@ static int serial8250_startup(struct uart_port *port) | |||
1991 | if (port->type == PORT_8250_CIR) | 1930 | if (port->type == PORT_8250_CIR) |
1992 | return -ENODEV; | 1931 | return -ENODEV; |
1993 | 1932 | ||
1994 | port->fifosize = uart_config[up->port.type].fifo_size; | 1933 | if (!port->fifosize) |
1995 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; | 1934 | port->fifosize = uart_config[port->type].fifo_size; |
1996 | up->capabilities = uart_config[up->port.type].flags; | 1935 | if (!up->tx_loadsz) |
1936 | up->tx_loadsz = uart_config[port->type].tx_loadsz; | ||
1937 | if (!up->capabilities) | ||
1938 | up->capabilities = uart_config[port->type].flags; | ||
1997 | up->mcr = 0; | 1939 | up->mcr = 0; |
1998 | 1940 | ||
1999 | if (port->iotype != up->cur_iotype) | 1941 | if (port->iotype != up->cur_iotype) |
@@ -2198,6 +2140,18 @@ dont_test_tx_en: | |||
2198 | up->msr_saved_flags = 0; | 2140 | up->msr_saved_flags = 0; |
2199 | 2141 | ||
2200 | /* | 2142 | /* |
2143 | * Request DMA channels for both RX and TX. | ||
2144 | */ | ||
2145 | if (up->dma) { | ||
2146 | retval = serial8250_request_dma(up); | ||
2147 | if (retval) { | ||
2148 | pr_warn_ratelimited("ttyS%d - failed to request DMA\n", | ||
2149 | serial_index(port)); | ||
2150 | up->dma = NULL; | ||
2151 | } | ||
2152 | } | ||
2153 | |||
2154 | /* | ||
2201 | * Finally, enable interrupts. Note: Modem status interrupts | 2155 | * Finally, enable interrupts. Note: Modem status interrupts |
2202 | * are set via set_termios(), which will be occurring imminently | 2156 | * are set via set_termios(), which will be occurring imminently |
2203 | * anyway, so we don't enable them here. | 2157 | * anyway, so we don't enable them here. |
@@ -2230,6 +2184,9 @@ static void serial8250_shutdown(struct uart_port *port) | |||
2230 | up->ier = 0; | 2184 | up->ier = 0; |
2231 | serial_port_out(port, UART_IER, 0); | 2185 | serial_port_out(port, UART_IER, 0); |
2232 | 2186 | ||
2187 | if (up->dma) | ||
2188 | serial8250_release_dma(up); | ||
2189 | |||
2233 | spin_lock_irqsave(&port->lock, flags); | 2190 | spin_lock_irqsave(&port->lock, flags); |
2234 | if (port->flags & UPF_FOURPORT) { | 2191 | if (port->flags & UPF_FOURPORT) { |
2235 | /* reset interrupts on the AST Fourport board */ | 2192 | /* reset interrupts on the AST Fourport board */ |
@@ -2826,9 +2783,12 @@ static void | |||
2826 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) | 2783 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) |
2827 | { | 2784 | { |
2828 | up->port.type = type; | 2785 | up->port.type = type; |
2829 | up->port.fifosize = uart_config[type].fifo_size; | 2786 | if (!up->port.fifosize) |
2830 | up->capabilities = uart_config[type].flags; | 2787 | up->port.fifosize = uart_config[type].fifo_size; |
2831 | up->tx_loadsz = uart_config[type].tx_loadsz; | 2788 | if (!up->tx_loadsz) |
2789 | up->tx_loadsz = uart_config[type].tx_loadsz; | ||
2790 | if (!up->capabilities) | ||
2791 | up->capabilities = uart_config[type].flags; | ||
2832 | } | 2792 | } |
2833 | 2793 | ||
2834 | static void __init | 2794 | static void __init |
@@ -3262,6 +3222,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3262 | uart->bugs = up->bugs; | 3222 | uart->bugs = up->bugs; |
3263 | uart->port.mapbase = up->port.mapbase; | 3223 | uart->port.mapbase = up->port.mapbase; |
3264 | uart->port.private_data = up->port.private_data; | 3224 | uart->port.private_data = up->port.private_data; |
3225 | uart->port.fifosize = up->port.fifosize; | ||
3226 | uart->tx_loadsz = up->tx_loadsz; | ||
3227 | uart->capabilities = up->capabilities; | ||
3228 | |||
3265 | if (up->port.dev) | 3229 | if (up->port.dev) |
3266 | uart->port.dev = up->port.dev; | 3230 | uart->port.dev = up->port.dev; |
3267 | 3231 | ||
@@ -3287,6 +3251,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3287 | uart->dl_read = up->dl_read; | 3251 | uart->dl_read = up->dl_read; |
3288 | if (up->dl_write) | 3252 | if (up->dl_write) |
3289 | uart->dl_write = up->dl_write; | 3253 | uart->dl_write = up->dl_write; |
3254 | if (up->dma) | ||
3255 | uart->dma = up->dma; | ||
3290 | 3256 | ||
3291 | if (serial8250_isa_config != NULL) | 3257 | if (serial8250_isa_config != NULL) |
3292 | serial8250_isa_config(0, &uart->port, | 3258 | serial8250_isa_config(0, &uart->port, |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 12caa1292b75..34eb676916fe 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -12,6 +12,35 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
15 | #include <linux/dmaengine.h> | ||
16 | |||
17 | struct uart_8250_dma { | ||
18 | dma_filter_fn fn; | ||
19 | void *rx_param; | ||
20 | void *tx_param; | ||
21 | |||
22 | int rx_chan_id; | ||
23 | int tx_chan_id; | ||
24 | |||
25 | struct dma_slave_config rxconf; | ||
26 | struct dma_slave_config txconf; | ||
27 | |||
28 | struct dma_chan *rxchan; | ||
29 | struct dma_chan *txchan; | ||
30 | |||
31 | dma_addr_t rx_addr; | ||
32 | dma_addr_t tx_addr; | ||
33 | |||
34 | dma_cookie_t rx_cookie; | ||
35 | dma_cookie_t tx_cookie; | ||
36 | |||
37 | void *rx_buf; | ||
38 | |||
39 | size_t rx_size; | ||
40 | size_t tx_size; | ||
41 | |||
42 | unsigned char tx_running:1; | ||
43 | }; | ||
15 | 44 | ||
16 | struct old_serial_port { | 45 | struct old_serial_port { |
17 | unsigned int uart; | 46 | unsigned int uart; |
@@ -143,3 +172,24 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt) | |||
143 | return 0; | 172 | return 0; |
144 | } | 173 | } |
145 | #endif | 174 | #endif |
175 | |||
176 | #ifdef CONFIG_SERIAL_8250_DMA | ||
177 | extern int serial8250_tx_dma(struct uart_8250_port *); | ||
178 | extern int serial8250_rx_dma(struct uart_8250_port *, unsigned int iir); | ||
179 | extern int serial8250_request_dma(struct uart_8250_port *); | ||
180 | extern void serial8250_release_dma(struct uart_8250_port *); | ||
181 | #else | ||
182 | static inline int serial8250_tx_dma(struct uart_8250_port *p) | ||
183 | { | ||
184 | return -1; | ||
185 | } | ||
186 | static inline int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | ||
187 | { | ||
188 | return -1; | ||
189 | } | ||
190 | static inline int serial8250_request_dma(struct uart_8250_port *p) | ||
191 | { | ||
192 | return -1; | ||
193 | } | ||
194 | static inline void serial8250_release_dma(struct uart_8250_port *p) { } | ||
195 | #endif | ||
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c new file mode 100644 index 000000000000..b9f7fd28112e --- /dev/null +++ b/drivers/tty/serial/8250/8250_dma.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * 8250_dma.c - DMA Engine API support for 8250.c | ||
3 | * | ||
4 | * Copyright (C) 2013 Intel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/tty.h> | ||
12 | #include <linux/tty_flip.h> | ||
13 | #include <linux/serial_reg.h> | ||
14 | #include <linux/dma-mapping.h> | ||
15 | |||
16 | #include "8250.h" | ||
17 | |||
18 | static void __dma_tx_complete(void *param) | ||
19 | { | ||
20 | struct uart_8250_port *p = param; | ||
21 | struct uart_8250_dma *dma = p->dma; | ||
22 | struct circ_buf *xmit = &p->port.state->xmit; | ||
23 | |||
24 | dma->tx_running = 0; | ||
25 | |||
26 | dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, | ||
27 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
28 | |||
29 | xmit->tail += dma->tx_size; | ||
30 | xmit->tail &= UART_XMIT_SIZE - 1; | ||
31 | p->port.icount.tx += dma->tx_size; | ||
32 | |||
33 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
34 | uart_write_wakeup(&p->port); | ||
35 | |||
36 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) { | ||
37 | serial8250_tx_dma(p); | ||
38 | uart_write_wakeup(&p->port); | ||
39 | } | ||
40 | } | ||
41 | |||
42 | static void __dma_rx_complete(void *param) | ||
43 | { | ||
44 | struct uart_8250_port *p = param; | ||
45 | struct uart_8250_dma *dma = p->dma; | ||
46 | struct tty_port *tty_port = &p->port.state->port; | ||
47 | struct dma_tx_state state; | ||
48 | int count; | ||
49 | |||
50 | dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, | ||
51 | dma->rx_size, DMA_FROM_DEVICE); | ||
52 | |||
53 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | ||
54 | dmaengine_terminate_all(dma->rxchan); | ||
55 | |||
56 | count = dma->rx_size - state.residue; | ||
57 | |||
58 | tty_insert_flip_string(tty_port, dma->rx_buf, count); | ||
59 | p->port.icount.rx += count; | ||
60 | |||
61 | tty_flip_buffer_push(tty_port); | ||
62 | } | ||
63 | |||
64 | int serial8250_tx_dma(struct uart_8250_port *p) | ||
65 | { | ||
66 | struct uart_8250_dma *dma = p->dma; | ||
67 | struct circ_buf *xmit = &p->port.state->xmit; | ||
68 | struct dma_async_tx_descriptor *desc; | ||
69 | |||
70 | if (dma->tx_running) | ||
71 | return -EBUSY; | ||
72 | |||
73 | dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
74 | if (!dma->tx_size) | ||
75 | return -EINVAL; | ||
76 | |||
77 | desc = dmaengine_prep_slave_single(dma->txchan, | ||
78 | dma->tx_addr + xmit->tail, | ||
79 | dma->tx_size, DMA_MEM_TO_DEV, | ||
80 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
81 | if (!desc) | ||
82 | return -EBUSY; | ||
83 | |||
84 | dma->tx_running = 1; | ||
85 | |||
86 | desc->callback = __dma_tx_complete; | ||
87 | desc->callback_param = p; | ||
88 | |||
89 | dma->tx_cookie = dmaengine_submit(desc); | ||
90 | |||
91 | dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr, | ||
92 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
93 | |||
94 | dma_async_issue_pending(dma->txchan); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | EXPORT_SYMBOL_GPL(serial8250_tx_dma); | ||
99 | |||
100 | int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | ||
101 | { | ||
102 | struct uart_8250_dma *dma = p->dma; | ||
103 | struct dma_async_tx_descriptor *desc; | ||
104 | struct dma_tx_state state; | ||
105 | int dma_status; | ||
106 | |||
107 | /* | ||
108 | * If RCVR FIFO trigger level was not reached, complete the transfer and | ||
109 | * let 8250.c copy the remaining data. | ||
110 | */ | ||
111 | if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) { | ||
112 | dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, | ||
113 | &state); | ||
114 | if (dma_status == DMA_IN_PROGRESS) { | ||
115 | dmaengine_pause(dma->rxchan); | ||
116 | __dma_rx_complete(p); | ||
117 | } | ||
118 | return -ETIMEDOUT; | ||
119 | } | ||
120 | |||
121 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, | ||
122 | dma->rx_size, DMA_DEV_TO_MEM, | ||
123 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
124 | if (!desc) | ||
125 | return -EBUSY; | ||
126 | |||
127 | desc->callback = __dma_rx_complete; | ||
128 | desc->callback_param = p; | ||
129 | |||
130 | dma->rx_cookie = dmaengine_submit(desc); | ||
131 | |||
132 | dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr, | ||
133 | dma->rx_size, DMA_FROM_DEVICE); | ||
134 | |||
135 | dma_async_issue_pending(dma->rxchan); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(serial8250_rx_dma); | ||
140 | |||
141 | int serial8250_request_dma(struct uart_8250_port *p) | ||
142 | { | ||
143 | struct uart_8250_dma *dma = p->dma; | ||
144 | dma_cap_mask_t mask; | ||
145 | |||
146 | dma->rxconf.src_addr = p->port.mapbase + UART_RX; | ||
147 | dma->txconf.dst_addr = p->port.mapbase + UART_TX; | ||
148 | |||
149 | dma_cap_zero(mask); | ||
150 | dma_cap_set(DMA_SLAVE, mask); | ||
151 | |||
152 | /* Get a channel for RX */ | ||
153 | dma->rxchan = dma_request_channel(mask, dma->fn, dma->rx_param); | ||
154 | if (!dma->rxchan) | ||
155 | return -ENODEV; | ||
156 | |||
157 | dmaengine_slave_config(dma->rxchan, &dma->rxconf); | ||
158 | |||
159 | /* Get a channel for TX */ | ||
160 | dma->txchan = dma_request_channel(mask, dma->fn, dma->tx_param); | ||
161 | if (!dma->txchan) { | ||
162 | dma_release_channel(dma->rxchan); | ||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
166 | dmaengine_slave_config(dma->txchan, &dma->txconf); | ||
167 | |||
168 | /* RX buffer */ | ||
169 | if (!dma->rx_size) | ||
170 | dma->rx_size = PAGE_SIZE; | ||
171 | |||
172 | dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size, | ||
173 | &dma->rx_addr, GFP_KERNEL); | ||
174 | if (!dma->rx_buf) { | ||
175 | dma_release_channel(dma->rxchan); | ||
176 | dma_release_channel(dma->txchan); | ||
177 | return -ENOMEM; | ||
178 | } | ||
179 | |||
180 | /* TX buffer */ | ||
181 | dma->tx_addr = dma_map_single(dma->txchan->device->dev, | ||
182 | p->port.state->xmit.buf, | ||
183 | UART_XMIT_SIZE, | ||
184 | DMA_TO_DEVICE); | ||
185 | |||
186 | dev_dbg_ratelimited(p->port.dev, "got both dma channels\n"); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | EXPORT_SYMBOL_GPL(serial8250_request_dma); | ||
191 | |||
192 | void serial8250_release_dma(struct uart_8250_port *p) | ||
193 | { | ||
194 | struct uart_8250_dma *dma = p->dma; | ||
195 | |||
196 | if (!dma) | ||
197 | return; | ||
198 | |||
199 | /* Release RX resources */ | ||
200 | dmaengine_terminate_all(dma->rxchan); | ||
201 | dma_free_coherent(dma->rxchan->device->dev, dma->rx_size, dma->rx_buf, | ||
202 | dma->rx_addr); | ||
203 | dma_release_channel(dma->rxchan); | ||
204 | dma->rxchan = NULL; | ||
205 | |||
206 | /* Release TX resources */ | ||
207 | dmaengine_terminate_all(dma->txchan); | ||
208 | dma_unmap_single(dma->txchan->device->dev, dma->tx_addr, | ||
209 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
210 | dma_release_channel(dma->txchan); | ||
211 | dma->txchan = NULL; | ||
212 | dma->tx_running = 0; | ||
213 | |||
214 | dev_dbg_ratelimited(p->port.dev, "dma channels released\n"); | ||
215 | } | ||
216 | EXPORT_SYMBOL_GPL(serial8250_release_dma); | ||
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 096d2ef48b32..db0e66f6dd0e 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Synopsys DesignWare 8250 driver. | 2 | * Synopsys DesignWare 8250 driver. |
3 | * | 3 | * |
4 | * Copyright 2011 Picochip, Jamie Iles. | 4 | * Copyright 2011 Picochip, Jamie Iles. |
5 | * Copyright 2013 Intel Corporation | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -24,6 +25,34 @@ | |||
24 | #include <linux/of_platform.h> | 25 | #include <linux/of_platform.h> |
25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/acpi.h> | ||
29 | |||
30 | #include "8250.h" | ||
31 | |||
32 | /* Offsets for the DesignWare specific registers */ | ||
33 | #define DW_UART_USR 0x1f /* UART Status Register */ | ||
34 | #define DW_UART_CPR 0xf4 /* Component Parameter Register */ | ||
35 | #define DW_UART_UCV 0xf8 /* UART Component Version */ | ||
36 | |||
37 | /* Intel Low Power Subsystem specific */ | ||
38 | #define LPSS_PRV_CLOCK_PARAMS 0x800 | ||
39 | |||
40 | /* Component Parameter Register bits */ | ||
41 | #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) | ||
42 | #define DW_UART_CPR_AFCE_MODE (1 << 4) | ||
43 | #define DW_UART_CPR_THRE_MODE (1 << 5) | ||
44 | #define DW_UART_CPR_SIR_MODE (1 << 6) | ||
45 | #define DW_UART_CPR_SIR_LP_MODE (1 << 7) | ||
46 | #define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8) | ||
47 | #define DW_UART_CPR_FIFO_ACCESS (1 << 9) | ||
48 | #define DW_UART_CPR_FIFO_STAT (1 << 10) | ||
49 | #define DW_UART_CPR_SHADOW (1 << 11) | ||
50 | #define DW_UART_CPR_ENCODED_PARMS (1 << 12) | ||
51 | #define DW_UART_CPR_DMA_EXTRA (1 << 13) | ||
52 | #define DW_UART_CPR_FIFO_MODE (0xff << 16) | ||
53 | /* Helper for fifo size calculation */ | ||
54 | #define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16) | ||
55 | |||
27 | 56 | ||
28 | struct dw8250_data { | 57 | struct dw8250_data { |
29 | int last_lcr; | 58 | int last_lcr; |
@@ -66,9 +95,6 @@ static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) | |||
66 | return readl(p->membase + offset); | 95 | return readl(p->membase + offset); |
67 | } | 96 | } |
68 | 97 | ||
69 | /* Offset for the DesignWare's UART Status Register. */ | ||
70 | #define UART_USR 0x1f | ||
71 | |||
72 | static int dw8250_handle_irq(struct uart_port *p) | 98 | static int dw8250_handle_irq(struct uart_port *p) |
73 | { | 99 | { |
74 | struct dw8250_data *d = p->private_data; | 100 | struct dw8250_data *d = p->private_data; |
@@ -78,7 +104,7 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
78 | return 1; | 104 | return 1; |
79 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | 105 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { |
80 | /* Clear the USR and write the LCR again. */ | 106 | /* Clear the USR and write the LCR again. */ |
81 | (void)p->serial_in(p, UART_USR); | 107 | (void)p->serial_in(p, DW_UART_USR); |
82 | p->serial_out(p, UART_LCR, d->last_lcr); | 108 | p->serial_out(p, UART_LCR, d->last_lcr); |
83 | 109 | ||
84 | return 1; | 110 | return 1; |
@@ -87,61 +113,210 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
87 | return 0; | 113 | return 0; |
88 | } | 114 | } |
89 | 115 | ||
116 | static int dw8250_probe_of(struct uart_port *p) | ||
117 | { | ||
118 | struct device_node *np = p->dev->of_node; | ||
119 | u32 val; | ||
120 | |||
121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | ||
122 | switch (val) { | ||
123 | case 1: | ||
124 | break; | ||
125 | case 4: | ||
126 | p->iotype = UPIO_MEM32; | ||
127 | p->serial_in = dw8250_serial_in32; | ||
128 | p->serial_out = dw8250_serial_out32; | ||
129 | break; | ||
130 | default: | ||
131 | dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | if (!of_property_read_u32(np, "reg-shift", &val)) | ||
137 | p->regshift = val; | ||
138 | |||
139 | if (of_property_read_u32(np, "clock-frequency", &val)) { | ||
140 | dev_err(p->dev, "no clock-frequency property set\n"); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | p->uartclk = val; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | #ifdef CONFIG_ACPI | ||
149 | static bool dw8250_acpi_dma_filter(struct dma_chan *chan, void *parm) | ||
150 | { | ||
151 | return chan->chan_id == *(int *)parm; | ||
152 | } | ||
153 | |||
154 | static acpi_status | ||
155 | dw8250_acpi_walk_resource(struct acpi_resource *res, void *data) | ||
156 | { | ||
157 | struct uart_port *p = data; | ||
158 | struct uart_8250_port *port; | ||
159 | struct uart_8250_dma *dma; | ||
160 | struct acpi_resource_fixed_dma *fixed_dma; | ||
161 | struct dma_slave_config *slave; | ||
162 | |||
163 | port = container_of(p, struct uart_8250_port, port); | ||
164 | |||
165 | switch (res->type) { | ||
166 | case ACPI_RESOURCE_TYPE_FIXED_DMA: | ||
167 | fixed_dma = &res->data.fixed_dma; | ||
168 | |||
169 | /* TX comes first */ | ||
170 | if (!port->dma) { | ||
171 | dma = devm_kzalloc(p->dev, sizeof(*dma), GFP_KERNEL); | ||
172 | if (!dma) | ||
173 | return AE_NO_MEMORY; | ||
174 | |||
175 | port->dma = dma; | ||
176 | slave = &dma->txconf; | ||
177 | |||
178 | slave->direction = DMA_MEM_TO_DEV; | ||
179 | slave->dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
180 | slave->slave_id = fixed_dma->request_lines; | ||
181 | slave->dst_maxburst = port->tx_loadsz / 4; | ||
182 | |||
183 | dma->tx_chan_id = fixed_dma->channels; | ||
184 | dma->tx_param = &dma->tx_chan_id; | ||
185 | dma->fn = dw8250_acpi_dma_filter; | ||
186 | } else { | ||
187 | dma = port->dma; | ||
188 | slave = &dma->rxconf; | ||
189 | |||
190 | slave->direction = DMA_DEV_TO_MEM; | ||
191 | slave->src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
192 | slave->slave_id = fixed_dma->request_lines; | ||
193 | slave->src_maxburst = p->fifosize / 4; | ||
194 | |||
195 | dma->rx_chan_id = fixed_dma->channels; | ||
196 | dma->rx_param = &dma->rx_chan_id; | ||
197 | } | ||
198 | |||
199 | break; | ||
200 | } | ||
201 | |||
202 | return AE_OK; | ||
203 | } | ||
204 | |||
205 | static int dw8250_probe_acpi(struct uart_port *p) | ||
206 | { | ||
207 | const struct acpi_device_id *id; | ||
208 | acpi_status status; | ||
209 | u32 reg; | ||
210 | |||
211 | id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); | ||
212 | if (!id) | ||
213 | return -ENODEV; | ||
214 | |||
215 | p->iotype = UPIO_MEM32; | ||
216 | p->serial_in = dw8250_serial_in32; | ||
217 | p->serial_out = dw8250_serial_out32; | ||
218 | p->regshift = 2; | ||
219 | p->uartclk = (unsigned int)id->driver_data; | ||
220 | |||
221 | status = acpi_walk_resources(ACPI_HANDLE(p->dev), METHOD_NAME__CRS, | ||
222 | dw8250_acpi_walk_resource, p); | ||
223 | if (ACPI_FAILURE(status)) { | ||
224 | dev_err_ratelimited(p->dev, "%s failed \"%s\"\n", __func__, | ||
225 | acpi_format_exception(status)); | ||
226 | return -ENODEV; | ||
227 | } | ||
228 | |||
229 | /* Fix Haswell issue where the clocks do not get enabled */ | ||
230 | if (!strcmp(id->id, "INT33C4") || !strcmp(id->id, "INT33C5")) { | ||
231 | reg = readl(p->membase + LPSS_PRV_CLOCK_PARAMS); | ||
232 | writel(reg | 1, p->membase + LPSS_PRV_CLOCK_PARAMS); | ||
233 | } | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | #else | ||
238 | static inline int dw8250_probe_acpi(struct uart_port *p) | ||
239 | { | ||
240 | return -ENODEV; | ||
241 | } | ||
242 | #endif /* CONFIG_ACPI */ | ||
243 | |||
244 | static void dw8250_setup_port(struct uart_8250_port *up) | ||
245 | { | ||
246 | struct uart_port *p = &up->port; | ||
247 | u32 reg = readl(p->membase + DW_UART_UCV); | ||
248 | |||
249 | /* | ||
250 | * If the Component Version Register returns zero, we know that | ||
251 | * ADDITIONAL_FEATURES are not enabled. No need to go any further. | ||
252 | */ | ||
253 | if (!reg) | ||
254 | return; | ||
255 | |||
256 | dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n", | ||
257 | (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); | ||
258 | |||
259 | reg = readl(p->membase + DW_UART_CPR); | ||
260 | if (!reg) | ||
261 | return; | ||
262 | |||
263 | /* Select the type based on fifo */ | ||
264 | if (reg & DW_UART_CPR_FIFO_MODE) { | ||
265 | p->type = PORT_16550A; | ||
266 | p->flags |= UPF_FIXED_TYPE; | ||
267 | p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); | ||
268 | up->tx_loadsz = p->fifosize; | ||
269 | } | ||
270 | } | ||
271 | |||
90 | static int dw8250_probe(struct platform_device *pdev) | 272 | static int dw8250_probe(struct platform_device *pdev) |
91 | { | 273 | { |
92 | struct uart_8250_port uart = {}; | 274 | struct uart_8250_port uart = {}; |
93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 275 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
94 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 276 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
95 | struct device_node *np = pdev->dev.of_node; | ||
96 | u32 val; | ||
97 | struct dw8250_data *data; | 277 | struct dw8250_data *data; |
278 | int err; | ||
98 | 279 | ||
99 | if (!regs || !irq) { | 280 | if (!regs || !irq) { |
100 | dev_err(&pdev->dev, "no registers/irq defined\n"); | 281 | dev_err(&pdev->dev, "no registers/irq defined\n"); |
101 | return -EINVAL; | 282 | return -EINVAL; |
102 | } | 283 | } |
103 | 284 | ||
104 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
105 | if (!data) | ||
106 | return -ENOMEM; | ||
107 | uart.port.private_data = data; | ||
108 | |||
109 | spin_lock_init(&uart.port.lock); | 285 | spin_lock_init(&uart.port.lock); |
110 | uart.port.mapbase = regs->start; | 286 | uart.port.mapbase = regs->start; |
111 | uart.port.irq = irq->start; | 287 | uart.port.irq = irq->start; |
112 | uart.port.handle_irq = dw8250_handle_irq; | 288 | uart.port.handle_irq = dw8250_handle_irq; |
113 | uart.port.type = PORT_8250; | 289 | uart.port.type = PORT_8250; |
114 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | | 290 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; |
115 | UPF_FIXED_PORT | UPF_FIXED_TYPE; | ||
116 | uart.port.dev = &pdev->dev; | 291 | uart.port.dev = &pdev->dev; |
117 | 292 | ||
293 | uart.port.membase = ioremap(regs->start, resource_size(regs)); | ||
294 | if (!uart.port.membase) | ||
295 | return -ENOMEM; | ||
296 | |||
118 | uart.port.iotype = UPIO_MEM; | 297 | uart.port.iotype = UPIO_MEM; |
119 | uart.port.serial_in = dw8250_serial_in; | 298 | uart.port.serial_in = dw8250_serial_in; |
120 | uart.port.serial_out = dw8250_serial_out; | 299 | uart.port.serial_out = dw8250_serial_out; |
121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | 300 | |
122 | switch (val) { | 301 | dw8250_setup_port(&uart); |
123 | case 1: | 302 | |
124 | break; | 303 | if (pdev->dev.of_node) { |
125 | case 4: | 304 | err = dw8250_probe_of(&uart.port); |
126 | uart.port.iotype = UPIO_MEM32; | 305 | if (err) |
127 | uart.port.serial_in = dw8250_serial_in32; | 306 | return err; |
128 | uart.port.serial_out = dw8250_serial_out32; | 307 | } else if (ACPI_HANDLE(&pdev->dev)) { |
129 | break; | 308 | err = dw8250_probe_acpi(&uart.port); |
130 | default: | 309 | if (err) |
131 | dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n", | 310 | return err; |
132 | val); | 311 | } else { |
133 | return -EINVAL; | 312 | return -ENODEV; |
134 | } | ||
135 | } | 313 | } |
136 | 314 | ||
137 | if (!of_property_read_u32(np, "reg-shift", &val)) | 315 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
138 | uart.port.regshift = val; | 316 | if (!data) |
317 | return -ENOMEM; | ||
139 | 318 | ||
140 | if (of_property_read_u32(np, "clock-frequency", &val)) { | 319 | uart.port.private_data = data; |
141 | dev_err(&pdev->dev, "no clock-frequency property set\n"); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | uart.port.uartclk = val; | ||
145 | 320 | ||
146 | data->line = serial8250_register_8250_port(&uart); | 321 | data->line = serial8250_register_8250_port(&uart); |
147 | if (data->line < 0) | 322 | if (data->line < 0) |
@@ -184,17 +359,25 @@ static int dw8250_resume(struct platform_device *pdev) | |||
184 | #define dw8250_resume NULL | 359 | #define dw8250_resume NULL |
185 | #endif /* CONFIG_PM */ | 360 | #endif /* CONFIG_PM */ |
186 | 361 | ||
187 | static const struct of_device_id dw8250_match[] = { | 362 | static const struct of_device_id dw8250_of_match[] = { |
188 | { .compatible = "snps,dw-apb-uart" }, | 363 | { .compatible = "snps,dw-apb-uart" }, |
189 | { /* Sentinel */ } | 364 | { /* Sentinel */ } |
190 | }; | 365 | }; |
191 | MODULE_DEVICE_TABLE(of, dw8250_match); | 366 | MODULE_DEVICE_TABLE(of, dw8250_of_match); |
367 | |||
368 | static const struct acpi_device_id dw8250_acpi_match[] = { | ||
369 | { "INT33C4", 100000000 }, | ||
370 | { "INT33C5", 100000000 }, | ||
371 | { }, | ||
372 | }; | ||
373 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | ||
192 | 374 | ||
193 | static struct platform_driver dw8250_platform_driver = { | 375 | static struct platform_driver dw8250_platform_driver = { |
194 | .driver = { | 376 | .driver = { |
195 | .name = "dw-apb-uart", | 377 | .name = "dw-apb-uart", |
196 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
197 | .of_match_table = dw8250_match, | 379 | .of_match_table = dw8250_of_match, |
380 | .acpi_match_table = ACPI_PTR(dw8250_acpi_match), | ||
198 | }, | 381 | }, |
199 | .probe = dw8250_probe, | 382 | .probe = dw8250_probe, |
200 | .remove = dw8250_remove, | 383 | .remove = dw8250_remove, |
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index f53a7db4350d..721904f8efa9 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c | |||
@@ -194,7 +194,7 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
194 | options++; | 194 | options++; |
195 | device->baud = simple_strtoul(options, NULL, 0); | 195 | device->baud = simple_strtoul(options, NULL, 0); |
196 | length = min(strcspn(options, " "), sizeof(device->options)); | 196 | length = min(strcspn(options, " "), sizeof(device->options)); |
197 | strncpy(device->options, options, length); | 197 | strlcpy(device->options, options, length); |
198 | } else { | 198 | } else { |
199 | device->baud = probe_baud(port); | 199 | device->baud = probe_baud(port); |
200 | snprintf(device->options, sizeof(device->options), "%u", | 200 | snprintf(device->options, sizeof(device->options), "%u", |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index a27a98e1b066..791c5a77ec61 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1040,6 +1040,253 @@ static int pci_asix_setup(struct serial_private *priv, | |||
1040 | return pci_default_setup(priv, board, port, idx); | 1040 | return pci_default_setup(priv, board, port, idx); |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | /* Quatech devices have their own extra interface features */ | ||
1044 | |||
1045 | struct quatech_feature { | ||
1046 | u16 devid; | ||
1047 | bool amcc; | ||
1048 | }; | ||
1049 | |||
1050 | #define QPCR_TEST_FOR1 0x3F | ||
1051 | #define QPCR_TEST_GET1 0x00 | ||
1052 | #define QPCR_TEST_FOR2 0x40 | ||
1053 | #define QPCR_TEST_GET2 0x40 | ||
1054 | #define QPCR_TEST_FOR3 0x80 | ||
1055 | #define QPCR_TEST_GET3 0x40 | ||
1056 | #define QPCR_TEST_FOR4 0xC0 | ||
1057 | #define QPCR_TEST_GET4 0x80 | ||
1058 | |||
1059 | #define QOPR_CLOCK_X1 0x0000 | ||
1060 | #define QOPR_CLOCK_X2 0x0001 | ||
1061 | #define QOPR_CLOCK_X4 0x0002 | ||
1062 | #define QOPR_CLOCK_X8 0x0003 | ||
1063 | #define QOPR_CLOCK_RATE_MASK 0x0003 | ||
1064 | |||
1065 | |||
1066 | static struct quatech_feature quatech_cards[] = { | ||
1067 | { PCI_DEVICE_ID_QUATECH_QSC100, 1 }, | ||
1068 | { PCI_DEVICE_ID_QUATECH_DSC100, 1 }, | ||
1069 | { PCI_DEVICE_ID_QUATECH_DSC100E, 0 }, | ||
1070 | { PCI_DEVICE_ID_QUATECH_DSC200, 1 }, | ||
1071 | { PCI_DEVICE_ID_QUATECH_DSC200E, 0 }, | ||
1072 | { PCI_DEVICE_ID_QUATECH_ESC100D, 1 }, | ||
1073 | { PCI_DEVICE_ID_QUATECH_ESC100M, 1 }, | ||
1074 | { PCI_DEVICE_ID_QUATECH_QSCP100, 1 }, | ||
1075 | { PCI_DEVICE_ID_QUATECH_DSCP100, 1 }, | ||
1076 | { PCI_DEVICE_ID_QUATECH_QSCP200, 1 }, | ||
1077 | { PCI_DEVICE_ID_QUATECH_DSCP200, 1 }, | ||
1078 | { PCI_DEVICE_ID_QUATECH_ESCLP100, 0 }, | ||
1079 | { PCI_DEVICE_ID_QUATECH_QSCLP100, 0 }, | ||
1080 | { PCI_DEVICE_ID_QUATECH_DSCLP100, 0 }, | ||
1081 | { PCI_DEVICE_ID_QUATECH_SSCLP100, 0 }, | ||
1082 | { PCI_DEVICE_ID_QUATECH_QSCLP200, 0 }, | ||
1083 | { PCI_DEVICE_ID_QUATECH_DSCLP200, 0 }, | ||
1084 | { PCI_DEVICE_ID_QUATECH_SSCLP200, 0 }, | ||
1085 | { PCI_DEVICE_ID_QUATECH_SPPXP_100, 0 }, | ||
1086 | { 0, } | ||
1087 | }; | ||
1088 | |||
1089 | static int pci_quatech_amcc(u16 devid) | ||
1090 | { | ||
1091 | struct quatech_feature *qf = &quatech_cards[0]; | ||
1092 | while (qf->devid) { | ||
1093 | if (qf->devid == devid) | ||
1094 | return qf->amcc; | ||
1095 | qf++; | ||
1096 | } | ||
1097 | pr_err("quatech: unknown port type '0x%04X'.\n", devid); | ||
1098 | return 0; | ||
1099 | }; | ||
1100 | |||
1101 | static int pci_quatech_rqopr(struct uart_8250_port *port) | ||
1102 | { | ||
1103 | unsigned long base = port->port.iobase; | ||
1104 | u8 LCR, val; | ||
1105 | |||
1106 | LCR = inb(base + UART_LCR); | ||
1107 | outb(0xBF, base + UART_LCR); | ||
1108 | val = inb(base + UART_SCR); | ||
1109 | outb(LCR, base + UART_LCR); | ||
1110 | return val; | ||
1111 | } | ||
1112 | |||
1113 | static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr) | ||
1114 | { | ||
1115 | unsigned long base = port->port.iobase; | ||
1116 | u8 LCR, val; | ||
1117 | |||
1118 | LCR = inb(base + UART_LCR); | ||
1119 | outb(0xBF, base + UART_LCR); | ||
1120 | val = inb(base + UART_SCR); | ||
1121 | outb(qopr, base + UART_SCR); | ||
1122 | outb(LCR, base + UART_LCR); | ||
1123 | } | ||
1124 | |||
1125 | static int pci_quatech_rqmcr(struct uart_8250_port *port) | ||
1126 | { | ||
1127 | unsigned long base = port->port.iobase; | ||
1128 | u8 LCR, val, qmcr; | ||
1129 | |||
1130 | LCR = inb(base + UART_LCR); | ||
1131 | outb(0xBF, base + UART_LCR); | ||
1132 | val = inb(base + UART_SCR); | ||
1133 | outb(val | 0x10, base + UART_SCR); | ||
1134 | qmcr = inb(base + UART_MCR); | ||
1135 | outb(val, base + UART_SCR); | ||
1136 | outb(LCR, base + UART_LCR); | ||
1137 | |||
1138 | return qmcr; | ||
1139 | } | ||
1140 | |||
1141 | static void pci_quatech_wqmcr(struct uart_8250_port *port, u8 qmcr) | ||
1142 | { | ||
1143 | unsigned long base = port->port.iobase; | ||
1144 | u8 LCR, val; | ||
1145 | |||
1146 | LCR = inb(base + UART_LCR); | ||
1147 | outb(0xBF, base + UART_LCR); | ||
1148 | val = inb(base + UART_SCR); | ||
1149 | outb(val | 0x10, base + UART_SCR); | ||
1150 | outb(qmcr, base + UART_MCR); | ||
1151 | outb(val, base + UART_SCR); | ||
1152 | outb(LCR, base + UART_LCR); | ||
1153 | } | ||
1154 | |||
1155 | static int pci_quatech_has_qmcr(struct uart_8250_port *port) | ||
1156 | { | ||
1157 | unsigned long base = port->port.iobase; | ||
1158 | u8 LCR, val; | ||
1159 | |||
1160 | LCR = inb(base + UART_LCR); | ||
1161 | outb(0xBF, base + UART_LCR); | ||
1162 | val = inb(base + UART_SCR); | ||
1163 | if (val & 0x20) { | ||
1164 | outb(0x80, UART_LCR); | ||
1165 | if (!(inb(UART_SCR) & 0x20)) { | ||
1166 | outb(LCR, base + UART_LCR); | ||
1167 | return 1; | ||
1168 | } | ||
1169 | } | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static int pci_quatech_test(struct uart_8250_port *port) | ||
1174 | { | ||
1175 | u8 reg; | ||
1176 | u8 qopr = pci_quatech_rqopr(port); | ||
1177 | pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1); | ||
1178 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1179 | if (reg != QPCR_TEST_GET1) | ||
1180 | return -EINVAL; | ||
1181 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR2); | ||
1182 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1183 | if (reg != QPCR_TEST_GET2) | ||
1184 | return -EINVAL; | ||
1185 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR3); | ||
1186 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1187 | if (reg != QPCR_TEST_GET3) | ||
1188 | return -EINVAL; | ||
1189 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR4); | ||
1190 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1191 | if (reg != QPCR_TEST_GET4) | ||
1192 | return -EINVAL; | ||
1193 | |||
1194 | pci_quatech_wqopr(port, qopr); | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | static int pci_quatech_clock(struct uart_8250_port *port) | ||
1199 | { | ||
1200 | u8 qopr, reg, set; | ||
1201 | unsigned long clock; | ||
1202 | |||
1203 | if (pci_quatech_test(port) < 0) | ||
1204 | return 1843200; | ||
1205 | |||
1206 | qopr = pci_quatech_rqopr(port); | ||
1207 | |||
1208 | pci_quatech_wqopr(port, qopr & ~QOPR_CLOCK_X8); | ||
1209 | reg = pci_quatech_rqopr(port); | ||
1210 | if (reg & QOPR_CLOCK_X8) { | ||
1211 | clock = 1843200; | ||
1212 | goto out; | ||
1213 | } | ||
1214 | pci_quatech_wqopr(port, qopr | QOPR_CLOCK_X8); | ||
1215 | reg = pci_quatech_rqopr(port); | ||
1216 | if (!(reg & QOPR_CLOCK_X8)) { | ||
1217 | clock = 1843200; | ||
1218 | goto out; | ||
1219 | } | ||
1220 | reg &= QOPR_CLOCK_X8; | ||
1221 | if (reg == QOPR_CLOCK_X2) { | ||
1222 | clock = 3685400; | ||
1223 | set = QOPR_CLOCK_X2; | ||
1224 | } else if (reg == QOPR_CLOCK_X4) { | ||
1225 | clock = 7372800; | ||
1226 | set = QOPR_CLOCK_X4; | ||
1227 | } else if (reg == QOPR_CLOCK_X8) { | ||
1228 | clock = 14745600; | ||
1229 | set = QOPR_CLOCK_X8; | ||
1230 | } else { | ||
1231 | clock = 1843200; | ||
1232 | set = QOPR_CLOCK_X1; | ||
1233 | } | ||
1234 | qopr &= ~QOPR_CLOCK_RATE_MASK; | ||
1235 | qopr |= set; | ||
1236 | |||
1237 | out: | ||
1238 | pci_quatech_wqopr(port, qopr); | ||
1239 | return clock; | ||
1240 | } | ||
1241 | |||
1242 | static int pci_quatech_rs422(struct uart_8250_port *port) | ||
1243 | { | ||
1244 | u8 qmcr; | ||
1245 | int rs422 = 0; | ||
1246 | |||
1247 | if (!pci_quatech_has_qmcr(port)) | ||
1248 | return 0; | ||
1249 | qmcr = pci_quatech_rqmcr(port); | ||
1250 | pci_quatech_wqmcr(port, 0xFF); | ||
1251 | if (pci_quatech_rqmcr(port)) | ||
1252 | rs422 = 1; | ||
1253 | pci_quatech_wqmcr(port, qmcr); | ||
1254 | return rs422; | ||
1255 | } | ||
1256 | |||
1257 | static int pci_quatech_init(struct pci_dev *dev) | ||
1258 | { | ||
1259 | if (pci_quatech_amcc(dev->device)) { | ||
1260 | unsigned long base = pci_resource_start(dev, 0); | ||
1261 | if (base) { | ||
1262 | u32 tmp; | ||
1263 | outl(inl(base + 0x38), base + 0x38); | ||
1264 | tmp = inl(base + 0x3c); | ||
1265 | outl(tmp | 0x01000000, base + 0x3c); | ||
1266 | outl(tmp, base + 0x3c); | ||
1267 | } | ||
1268 | } | ||
1269 | return 0; | ||
1270 | } | ||
1271 | |||
1272 | static int pci_quatech_setup(struct serial_private *priv, | ||
1273 | const struct pciserial_board *board, | ||
1274 | struct uart_8250_port *port, int idx) | ||
1275 | { | ||
1276 | /* Needed by pci_quatech calls below */ | ||
1277 | port->port.iobase = pci_resource_start(priv->dev, FL_GET_BASE(board->flags)); | ||
1278 | /* Set up the clocking */ | ||
1279 | port->port.uartclk = pci_quatech_clock(port); | ||
1280 | /* For now just warn about RS422 */ | ||
1281 | if (pci_quatech_rs422(port)) | ||
1282 | pr_warn("quatech: software control of RS422 features not currently supported.\n"); | ||
1283 | return pci_default_setup(priv, board, port, idx); | ||
1284 | } | ||
1285 | |||
1286 | static void pci_quatech_exit(struct pci_dev *dev) | ||
1287 | { | ||
1288 | } | ||
1289 | |||
1043 | static int pci_default_setup(struct serial_private *priv, | 1290 | static int pci_default_setup(struct serial_private *priv, |
1044 | const struct pciserial_board *board, | 1291 | const struct pciserial_board *board, |
1045 | struct uart_8250_port *port, int idx) | 1292 | struct uart_8250_port *port, int idx) |
@@ -1318,6 +1565,9 @@ pci_wch_ch353_setup(struct serial_private *priv, | |||
1318 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 | 1565 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 |
1319 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a | 1566 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a |
1320 | 1567 | ||
1568 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 | ||
1569 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 | ||
1570 | |||
1321 | 1571 | ||
1322 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1572 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1323 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1573 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -1541,6 +1791,16 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1541 | .setup = pci_ni8430_setup, | 1791 | .setup = pci_ni8430_setup, |
1542 | .exit = pci_ni8430_exit, | 1792 | .exit = pci_ni8430_exit, |
1543 | }, | 1793 | }, |
1794 | /* Quatech */ | ||
1795 | { | ||
1796 | .vendor = PCI_VENDOR_ID_QUATECH, | ||
1797 | .device = PCI_ANY_ID, | ||
1798 | .subvendor = PCI_ANY_ID, | ||
1799 | .subdevice = PCI_ANY_ID, | ||
1800 | .init = pci_quatech_init, | ||
1801 | .setup = pci_quatech_setup, | ||
1802 | .exit = pci_quatech_exit, | ||
1803 | }, | ||
1544 | /* | 1804 | /* |
1545 | * Panacom | 1805 | * Panacom |
1546 | */ | 1806 | */ |
@@ -1704,6 +1964,23 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1704 | .setup = pci_timedia_setup, | 1964 | .setup = pci_timedia_setup, |
1705 | }, | 1965 | }, |
1706 | /* | 1966 | /* |
1967 | * SUNIX (Timedia) cards | ||
1968 | * Do not "probe" for these cards as there is at least one combination | ||
1969 | * card that should be handled by parport_pc that doesn't match the | ||
1970 | * rule in pci_timedia_probe. | ||
1971 | * It is part number is MIO5079A but its subdevice ID is 0x0102. | ||
1972 | * There are some boards with part number SER5037AL that report | ||
1973 | * subdevice ID 0x0002. | ||
1974 | */ | ||
1975 | { | ||
1976 | .vendor = PCI_VENDOR_ID_SUNIX, | ||
1977 | .device = PCI_DEVICE_ID_SUNIX_1999, | ||
1978 | .subvendor = PCI_VENDOR_ID_SUNIX, | ||
1979 | .subdevice = PCI_ANY_ID, | ||
1980 | .init = pci_timedia_init, | ||
1981 | .setup = pci_timedia_setup, | ||
1982 | }, | ||
1983 | /* | ||
1707 | * Exar cards | 1984 | * Exar cards |
1708 | */ | 1985 | */ |
1709 | { | 1986 | { |
@@ -3506,18 +3783,70 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3506 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, | 3783 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, |
3507 | 0x10b5, 0x106a, 0, 0, | 3784 | 0x10b5, 0x106a, 0, 0, |
3508 | pbn_plx_romulus }, | 3785 | pbn_plx_romulus }, |
3786 | /* | ||
3787 | * Quatech cards. These actually have configurable clocks but for | ||
3788 | * now we just use the default. | ||
3789 | * | ||
3790 | * 100 series are RS232, 200 series RS422, | ||
3791 | */ | ||
3509 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, | 3792 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, |
3510 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3793 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3511 | pbn_b1_4_115200 }, | 3794 | pbn_b1_4_115200 }, |
3512 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100, | 3795 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100, |
3513 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3796 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3514 | pbn_b1_2_115200 }, | 3797 | pbn_b1_2_115200 }, |
3798 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100E, | ||
3799 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3800 | pbn_b2_2_115200 }, | ||
3801 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200, | ||
3802 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3803 | pbn_b1_2_115200 }, | ||
3804 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200E, | ||
3805 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3806 | pbn_b2_2_115200 }, | ||
3807 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC200, | ||
3808 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3809 | pbn_b1_4_115200 }, | ||
3515 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D, | 3810 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D, |
3516 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3811 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3517 | pbn_b1_8_115200 }, | 3812 | pbn_b1_8_115200 }, |
3518 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, | 3813 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, |
3519 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3814 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3520 | pbn_b1_8_115200 }, | 3815 | pbn_b1_8_115200 }, |
3816 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP100, | ||
3817 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3818 | pbn_b1_4_115200 }, | ||
3819 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP100, | ||
3820 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3821 | pbn_b1_2_115200 }, | ||
3822 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP200, | ||
3823 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3824 | pbn_b1_4_115200 }, | ||
3825 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP200, | ||
3826 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3827 | pbn_b1_2_115200 }, | ||
3828 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP100, | ||
3829 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3830 | pbn_b2_4_115200 }, | ||
3831 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP100, | ||
3832 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3833 | pbn_b2_2_115200 }, | ||
3834 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP100, | ||
3835 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3836 | pbn_b2_1_115200 }, | ||
3837 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP200, | ||
3838 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3839 | pbn_b2_4_115200 }, | ||
3840 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP200, | ||
3841 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3842 | pbn_b2_2_115200 }, | ||
3843 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP200, | ||
3844 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3845 | pbn_b2_1_115200 }, | ||
3846 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESCLP100, | ||
3847 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3848 | pbn_b0_8_115200 }, | ||
3849 | |||
3521 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, | 3850 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, |
3522 | PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, | 3851 | PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, |
3523 | 0, 0, | 3852 | 0, 0, |
@@ -3902,6 +4231,19 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3902 | pbn_b0_bt_1_921600 }, | 4231 | pbn_b0_bt_1_921600 }, |
3903 | 4232 | ||
3904 | /* | 4233 | /* |
4234 | * SUNIX (TIMEDIA) | ||
4235 | */ | ||
4236 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, | ||
4237 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, | ||
4238 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, | ||
4239 | pbn_b0_bt_1_921600 }, | ||
4240 | |||
4241 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, | ||
4242 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, | ||
4243 | PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, | ||
4244 | pbn_b0_bt_1_921600 }, | ||
4245 | |||
4246 | /* | ||
3905 | * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> | 4247 | * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> |
3906 | */ | 4248 | */ |
3907 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, | 4249 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, |
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c31133a6ea8e..2ef9537bcb2c 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -84,6 +84,14 @@ config SERIAL_8250_GSC | |||
84 | depends on SERIAL_8250 && GSC | 84 | depends on SERIAL_8250 && GSC |
85 | default SERIAL_8250 | 85 | default SERIAL_8250 |
86 | 86 | ||
87 | config SERIAL_8250_DMA | ||
88 | bool "DMA support for 16550 compatible UART controllers" if EXPERT | ||
89 | depends on SERIAL_8250 && DMADEVICES=y | ||
90 | default SERIAL_8250 | ||
91 | help | ||
92 | This builds DMA support that can be used with 8250/16650 | ||
93 | compatible UART controllers that support DMA signaling. | ||
94 | |||
87 | config SERIAL_8250_PCI | 95 | config SERIAL_8250_PCI |
88 | tristate "8250/16550 PCI device support" if EXPERT | 96 | tristate "8250/16550 PCI device support" if EXPERT |
89 | depends on SERIAL_8250 && PCI | 97 | depends on SERIAL_8250 && PCI |
@@ -249,15 +257,6 @@ config SERIAL_8250_ACORN | |||
249 | system, say Y to this option. The driver can handle 1, 2, or 3 port | 257 | system, say Y to this option. The driver can handle 1, 2, or 3 port |
250 | cards. If unsure, say N. | 258 | cards. If unsure, say N. |
251 | 259 | ||
252 | config SERIAL_8250_RM9K | ||
253 | bool "Support for MIPS RM9xxx integrated serial port" | ||
254 | depends on SERIAL_8250 != n && SERIAL_RM9000 | ||
255 | select SERIAL_8250_SHARE_IRQ | ||
256 | help | ||
257 | Selecting this option will add support for the integrated serial | ||
258 | port hardware found on MIPS RM9122 and similar processors. | ||
259 | If unsure, say N. | ||
260 | |||
261 | config SERIAL_8250_FSL | 260 | config SERIAL_8250_FSL |
262 | bool | 261 | bool |
263 | depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 | 262 | depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 |
@@ -265,7 +264,7 @@ config SERIAL_8250_FSL | |||
265 | 264 | ||
266 | config SERIAL_8250_DW | 265 | config SERIAL_8250_DW |
267 | tristate "Support for Synopsys DesignWare 8250 quirks" | 266 | tristate "Support for Synopsys DesignWare 8250 quirks" |
268 | depends on SERIAL_8250 && OF | 267 | depends on SERIAL_8250 |
269 | help | 268 | help |
270 | Selecting this option will enable handling of the extra features | 269 | Selecting this option will enable handling of the extra features |
271 | present in the Synopsys DesignWare APB UART. | 270 | present in the Synopsys DesignWare APB UART. |
@@ -277,3 +276,11 @@ config SERIAL_8250_EM | |||
277 | Selecting this option will add support for the integrated serial | 276 | Selecting this option will add support for the integrated serial |
278 | port hardware found on the Emma Mobile line of processors. | 277 | port hardware found on the Emma Mobile line of processors. |
279 | If unsure, say N. | 278 | If unsure, say N. |
279 | |||
280 | config SERIAL_8250_RT288X | ||
281 | bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" | ||
282 | depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883) | ||
283 | help | ||
284 | If you have a Ralink RT288x/RT305x SoC based board and want to use the | ||
285 | serial port, say Y to this option. The driver can handle up to 2 serial | ||
286 | ports. If unsure, say N. | ||
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 108fe7fe13e2..a23838a4d535 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | obj-$(CONFIG_SERIAL_8250) += 8250_core.o | 5 | obj-$(CONFIG_SERIAL_8250) += 8250_core.o |
6 | 8250_core-y := 8250.o | 6 | 8250_core-y := 8250.o |
7 | 8250_core-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o | 7 | 8250_core-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o |
8 | 8250_core-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o | ||
8 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o | 9 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o |
9 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o | 10 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o |
10 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o | 11 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 59c23d038106..a0162cbf0557 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -2,8 +2,10 @@ | |||
2 | # Serial device configuration | 2 | # Serial device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | if TTY | ||
6 | |||
5 | menu "Serial drivers" | 7 | menu "Serial drivers" |
6 | depends on HAS_IOMEM | 8 | depends on HAS_IOMEM && GENERIC_HARDIRQS |
7 | 9 | ||
8 | source "drivers/tty/serial/8250/Kconfig" | 10 | source "drivers/tty/serial/8250/Kconfig" |
9 | 11 | ||
@@ -269,6 +271,17 @@ config SERIAL_SIRFSOC_CONSOLE | |||
269 | your boot loader about how to pass options to the kernel at | 271 | your boot loader about how to pass options to the kernel at |
270 | boot time.) | 272 | boot time.) |
271 | 273 | ||
274 | config SERIAL_TEGRA | ||
275 | tristate "NVIDIA Tegra20/30 SoC serial controller" | ||
276 | depends on ARCH_TEGRA && TEGRA20_APB_DMA | ||
277 | select SERIAL_CORE | ||
278 | help | ||
279 | Support for the on-chip UARTs on the NVIDIA Tegra series SOCs | ||
280 | providing /dev/ttyHS0, 1, 2, 3 and 4 (note, some machines may not | ||
281 | provide all of these ports, depending on how the serial port | ||
282 | are enabled). This driver uses the APB DMA to achieve higher baudrate | ||
283 | and better performance. | ||
284 | |||
272 | config SERIAL_MAX3100 | 285 | config SERIAL_MAX3100 |
273 | tristate "MAX3100 support" | 286 | tristate "MAX3100 support" |
274 | depends on SPI | 287 | depends on SPI |
@@ -1447,4 +1460,30 @@ config SERIAL_ARC_NR_PORTS | |||
1447 | Set this to the number of serial ports you want the driver | 1460 | Set this to the number of serial ports you want the driver |
1448 | to support. | 1461 | to support. |
1449 | 1462 | ||
1463 | config SERIAL_RP2 | ||
1464 | tristate "Comtrol RocketPort EXPRESS/INFINITY support" | ||
1465 | depends on PCI | ||
1466 | select SERIAL_CORE | ||
1467 | help | ||
1468 | This driver supports the Comtrol RocketPort EXPRESS and | ||
1469 | RocketPort INFINITY families of PCI/PCIe multiport serial adapters. | ||
1470 | These adapters use a "RocketPort 2" ASIC that is not compatible | ||
1471 | with the original RocketPort driver (CONFIG_ROCKETPORT). | ||
1472 | |||
1473 | To compile this driver as a module, choose M here: the | ||
1474 | module will be called rp2. | ||
1475 | |||
1476 | If you want to compile this driver into the kernel, say Y here. If | ||
1477 | you don't have a suitable RocketPort card installed, say N. | ||
1478 | |||
1479 | config SERIAL_RP2_NR_UARTS | ||
1480 | int "Maximum number of RocketPort EXPRESS/INFINITY ports" | ||
1481 | depends on SERIAL_RP2 | ||
1482 | default "32" | ||
1483 | help | ||
1484 | If multiple cards are present, the default limit of 32 ports may | ||
1485 | need to be increased. | ||
1486 | |||
1450 | endmenu | 1487 | endmenu |
1488 | |||
1489 | endif # TTY | ||
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index df1b998c436b..eedfec40e3dd 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -80,6 +80,8 @@ obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o | |||
80 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | 80 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o |
81 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | 81 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o |
82 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o | 82 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o |
83 | obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o | ||
83 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o | 84 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o |
84 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o | 85 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o |
85 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o | 86 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o |
87 | obj-$(CONFIG_SERIAL_RP2) += rp2.o | ||
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 872f14ae43d2..c6bdb943726b 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c | |||
@@ -139,7 +139,7 @@ static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) | |||
139 | uart_insert_char(port, 0, 0, ch, flag); | 139 | uart_insert_char(port, 0, 0, ch, flag); |
140 | } | 140 | } |
141 | 141 | ||
142 | tty_flip_buffer_push(port->state->port.tty); | 142 | tty_flip_buffer_push(&port->state->port); |
143 | } | 143 | } |
144 | 144 | ||
145 | static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) | 145 | static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) |
@@ -493,11 +493,9 @@ static int __init altera_jtaguart_init(void) | |||
493 | if (rc) | 493 | if (rc) |
494 | return rc; | 494 | return rc; |
495 | rc = platform_driver_register(&altera_jtaguart_platform_driver); | 495 | rc = platform_driver_register(&altera_jtaguart_platform_driver); |
496 | if (rc) { | 496 | if (rc) |
497 | uart_unregister_driver(&altera_jtaguart_driver); | 497 | uart_unregister_driver(&altera_jtaguart_driver); |
498 | return rc; | 498 | return rc; |
499 | } | ||
500 | return 0; | ||
501 | } | 499 | } |
502 | 500 | ||
503 | static void __exit altera_jtaguart_exit(void) | 501 | static void __exit altera_jtaguart_exit(void) |
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 684a0808e1c7..13471dd95793 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -231,7 +231,7 @@ static void altera_uart_rx_chars(struct altera_uart *pp) | |||
231 | flag); | 231 | flag); |
232 | } | 232 | } |
233 | 233 | ||
234 | tty_flip_buffer_push(port->state->port.tty); | 234 | tty_flip_buffer_push(&port->state->port); |
235 | } | 235 | } |
236 | 236 | ||
237 | static void altera_uart_tx_chars(struct altera_uart *pp) | 237 | static void altera_uart_tx_chars(struct altera_uart *pp) |
@@ -637,11 +637,9 @@ static int __init altera_uart_init(void) | |||
637 | if (rc) | 637 | if (rc) |
638 | return rc; | 638 | return rc; |
639 | rc = platform_driver_register(&altera_uart_platform_driver); | 639 | rc = platform_driver_register(&altera_uart_platform_driver); |
640 | if (rc) { | 640 | if (rc) |
641 | uart_unregister_driver(&altera_uart_driver); | 641 | uart_unregister_driver(&altera_uart_driver); |
642 | return rc; | 642 | return rc; |
643 | } | ||
644 | return 0; | ||
645 | } | 643 | } |
646 | 644 | ||
647 | static void __exit altera_uart_exit(void) | 645 | static void __exit altera_uart_exit(void) |
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 22317dd16474..c36840519527 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c | |||
@@ -116,7 +116,6 @@ static void pl010_enable_ms(struct uart_port *port) | |||
116 | 116 | ||
117 | static void pl010_rx_chars(struct uart_amba_port *uap) | 117 | static void pl010_rx_chars(struct uart_amba_port *uap) |
118 | { | 118 | { |
119 | struct tty_struct *tty = uap->port.state->port.tty; | ||
120 | unsigned int status, ch, flag, rsr, max_count = 256; | 119 | unsigned int status, ch, flag, rsr, max_count = 256; |
121 | 120 | ||
122 | status = readb(uap->port.membase + UART01x_FR); | 121 | status = readb(uap->port.membase + UART01x_FR); |
@@ -165,7 +164,7 @@ static void pl010_rx_chars(struct uart_amba_port *uap) | |||
165 | status = readb(uap->port.membase + UART01x_FR); | 164 | status = readb(uap->port.membase + UART01x_FR); |
166 | } | 165 | } |
167 | spin_unlock(&uap->port.lock); | 166 | spin_unlock(&uap->port.lock); |
168 | tty_flip_buffer_push(tty); | 167 | tty_flip_buffer_push(&uap->port.state->port); |
169 | spin_lock(&uap->port.lock); | 168 | spin_lock(&uap->port.lock); |
170 | } | 169 | } |
171 | 170 | ||
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 7fca4022a8b2..3ea5408fcbeb 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -698,7 +698,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
698 | u32 pending, bool use_buf_b, | 698 | u32 pending, bool use_buf_b, |
699 | bool readfifo) | 699 | bool readfifo) |
700 | { | 700 | { |
701 | struct tty_struct *tty = uap->port.state->port.tty; | 701 | struct tty_port *port = &uap->port.state->port; |
702 | struct pl011_sgbuf *sgbuf = use_buf_b ? | 702 | struct pl011_sgbuf *sgbuf = use_buf_b ? |
703 | &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; | 703 | &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; |
704 | struct device *dev = uap->dmarx.chan->device->dev; | 704 | struct device *dev = uap->dmarx.chan->device->dev; |
@@ -715,8 +715,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
715 | * Note that tty_insert_flip_buf() tries to take as many chars | 715 | * Note that tty_insert_flip_buf() tries to take as many chars |
716 | * as it can. | 716 | * as it can. |
717 | */ | 717 | */ |
718 | dma_count = tty_insert_flip_string(uap->port.state->port.tty, | 718 | dma_count = tty_insert_flip_string(port, sgbuf->buf, pending); |
719 | sgbuf->buf, pending); | ||
720 | 719 | ||
721 | /* Return buffer to device */ | 720 | /* Return buffer to device */ |
722 | dma_sync_sg_for_device(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE); | 721 | dma_sync_sg_for_device(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE); |
@@ -754,7 +753,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
754 | dev_vdbg(uap->port.dev, | 753 | dev_vdbg(uap->port.dev, |
755 | "Took %d chars from DMA buffer and %d chars from the FIFO\n", | 754 | "Took %d chars from DMA buffer and %d chars from the FIFO\n", |
756 | dma_count, fifotaken); | 755 | dma_count, fifotaken); |
757 | tty_flip_buffer_push(tty); | 756 | tty_flip_buffer_push(port); |
758 | spin_lock(&uap->port.lock); | 757 | spin_lock(&uap->port.lock); |
759 | } | 758 | } |
760 | 759 | ||
@@ -1076,12 +1075,10 @@ static void pl011_enable_ms(struct uart_port *port) | |||
1076 | 1075 | ||
1077 | static void pl011_rx_chars(struct uart_amba_port *uap) | 1076 | static void pl011_rx_chars(struct uart_amba_port *uap) |
1078 | { | 1077 | { |
1079 | struct tty_struct *tty = uap->port.state->port.tty; | ||
1080 | |||
1081 | pl011_fifo_to_tty(uap); | 1078 | pl011_fifo_to_tty(uap); |
1082 | 1079 | ||
1083 | spin_unlock(&uap->port.lock); | 1080 | spin_unlock(&uap->port.lock); |
1084 | tty_flip_buffer_push(tty); | 1081 | tty_flip_buffer_push(&uap->port.state->port); |
1085 | /* | 1082 | /* |
1086 | * If we were temporarily out of DMA mode for a while, | 1083 | * If we were temporarily out of DMA mode for a while, |
1087 | * attempt to switch back to DMA mode again. | 1084 | * attempt to switch back to DMA mode again. |
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 59ae2b53e765..6331464d9101 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c | |||
@@ -78,7 +78,6 @@ static void apbuart_enable_ms(struct uart_port *port) | |||
78 | 78 | ||
79 | static void apbuart_rx_chars(struct uart_port *port) | 79 | static void apbuart_rx_chars(struct uart_port *port) |
80 | { | 80 | { |
81 | struct tty_struct *tty = port->state->port.tty; | ||
82 | unsigned int status, ch, rsr, flag; | 81 | unsigned int status, ch, rsr, flag; |
83 | unsigned int max_chars = port->fifosize; | 82 | unsigned int max_chars = port->fifosize; |
84 | 83 | ||
@@ -126,7 +125,7 @@ static void apbuart_rx_chars(struct uart_port *port) | |||
126 | status = UART_GET_STATUS(port); | 125 | status = UART_GET_STATUS(port); |
127 | } | 126 | } |
128 | 127 | ||
129 | tty_flip_buffer_push(tty); | 128 | tty_flip_buffer_push(&port->state->port); |
130 | } | 129 | } |
131 | 130 | ||
132 | static void apbuart_tx_chars(struct uart_port *port) | 131 | static void apbuart_tx_chars(struct uart_port *port) |
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 505c490c0b44..27f20c57abed 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c | |||
@@ -297,10 +297,9 @@ static void ar933x_uart_set_termios(struct uart_port *port, | |||
297 | 297 | ||
298 | static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | 298 | static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) |
299 | { | 299 | { |
300 | struct tty_struct *tty; | 300 | struct tty_port *port = &up->port.state->port; |
301 | int max_count = 256; | 301 | int max_count = 256; |
302 | 302 | ||
303 | tty = tty_port_tty_get(&up->port.state->port); | ||
304 | do { | 303 | do { |
305 | unsigned int rdata; | 304 | unsigned int rdata; |
306 | unsigned char ch; | 305 | unsigned char ch; |
@@ -313,11 +312,6 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | |||
313 | ar933x_uart_write(up, AR933X_UART_DATA_REG, | 312 | ar933x_uart_write(up, AR933X_UART_DATA_REG, |
314 | AR933X_UART_DATA_RX_CSR); | 313 | AR933X_UART_DATA_RX_CSR); |
315 | 314 | ||
316 | if (!tty) { | ||
317 | /* discard the data if no tty available */ | ||
318 | continue; | ||
319 | } | ||
320 | |||
321 | up->port.icount.rx++; | 315 | up->port.icount.rx++; |
322 | ch = rdata & AR933X_UART_DATA_TX_RX_MASK; | 316 | ch = rdata & AR933X_UART_DATA_TX_RX_MASK; |
323 | 317 | ||
@@ -325,13 +319,10 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | |||
325 | continue; | 319 | continue; |
326 | 320 | ||
327 | if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) | 321 | if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) |
328 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 322 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
329 | } while (max_count-- > 0); | 323 | } while (max_count-- > 0); |
330 | 324 | ||
331 | if (tty) { | 325 | tty_flip_buffer_push(port); |
332 | tty_flip_buffer_push(tty); | ||
333 | tty_kref_put(tty); | ||
334 | } | ||
335 | } | 326 | } |
336 | 327 | ||
337 | static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) | 328 | static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) |
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 3e0b3fac6a0e..d97e194b6bc5 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <linux/tty_flip.h> | 37 | #include <linux/tty_flip.h> |
38 | #include <linux/serial_core.h> | 38 | #include <linux/serial_core.h> |
39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
40 | #include <linux/of.h> | ||
41 | #include <linux/of_platform.h> | ||
40 | 42 | ||
41 | /************************************* | 43 | /************************************* |
42 | * ARC UART Hardware Specs | 44 | * ARC UART Hardware Specs |
@@ -209,12 +211,8 @@ static void arc_serial_start_tx(struct uart_port *port) | |||
209 | 211 | ||
210 | static void arc_serial_rx_chars(struct arc_uart_port *uart) | 212 | static void arc_serial_rx_chars(struct arc_uart_port *uart) |
211 | { | 213 | { |
212 | struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port); | ||
213 | unsigned int status, ch, flg = 0; | 214 | unsigned int status, ch, flg = 0; |
214 | 215 | ||
215 | if (!tty) | ||
216 | return; | ||
217 | |||
218 | /* | 216 | /* |
219 | * UART has 4 deep RX-FIFO. Driver's recongnition of this fact | 217 | * UART has 4 deep RX-FIFO. Driver's recongnition of this fact |
220 | * is very subtle. Here's how ... | 218 | * is very subtle. Here's how ... |
@@ -250,10 +248,8 @@ static void arc_serial_rx_chars(struct arc_uart_port *uart) | |||
250 | uart_insert_char(&uart->port, status, RXOERR, ch, flg); | 248 | uart_insert_char(&uart->port, status, RXOERR, ch, flg); |
251 | 249 | ||
252 | done: | 250 | done: |
253 | tty_flip_buffer_push(tty); | 251 | tty_flip_buffer_push(&uart->port.state->port); |
254 | } | 252 | } |
255 | |||
256 | tty_kref_put(tty); | ||
257 | } | 253 | } |
258 | 254 | ||
259 | /* | 255 | /* |
@@ -526,18 +522,37 @@ static struct uart_ops arc_serial_pops = { | |||
526 | }; | 522 | }; |
527 | 523 | ||
528 | static int | 524 | static int |
529 | arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | 525 | arc_uart_init_one(struct platform_device *pdev, int dev_id) |
530 | { | 526 | { |
531 | struct resource *res, *res2; | 527 | struct resource *res, *res2; |
532 | unsigned long *plat_data; | 528 | unsigned long *plat_data; |
533 | 529 | struct arc_uart_port *uart = &arc_uart_ports[dev_id]; | |
534 | if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) { | ||
535 | dev_err(&pdev->dev, "Wrong uart platform device id.\n"); | ||
536 | return -ENOENT; | ||
537 | } | ||
538 | 530 | ||
539 | plat_data = ((unsigned long *)(pdev->dev.platform_data)); | 531 | plat_data = ((unsigned long *)(pdev->dev.platform_data)); |
540 | uart->baud = plat_data[0]; | 532 | if (!plat_data) |
533 | return -ENODEV; | ||
534 | |||
535 | uart->is_emulated = !!plat_data[0]; /* workaround ISS bug */ | ||
536 | |||
537 | if (is_early_platform_device(pdev)) { | ||
538 | uart->port.uartclk = plat_data[1]; | ||
539 | uart->baud = plat_data[2]; | ||
540 | } else { | ||
541 | struct device_node *np = pdev->dev.of_node; | ||
542 | u32 val; | ||
543 | |||
544 | if (of_property_read_u32(np, "clock-frequency", &val)) { | ||
545 | dev_err(&pdev->dev, "clock-frequency property NOTset\n"); | ||
546 | return -EINVAL; | ||
547 | } | ||
548 | uart->port.uartclk = val; | ||
549 | |||
550 | if (of_property_read_u32(np, "current-speed", &val)) { | ||
551 | dev_err(&pdev->dev, "current-speed property NOT set\n"); | ||
552 | return -EINVAL; | ||
553 | } | ||
554 | uart->baud = val; | ||
555 | } | ||
541 | 556 | ||
542 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 557 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
543 | if (!res) | 558 | if (!res) |
@@ -557,10 +572,9 @@ arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | |||
557 | uart->port.dev = &pdev->dev; | 572 | uart->port.dev = &pdev->dev; |
558 | uart->port.iotype = UPIO_MEM; | 573 | uart->port.iotype = UPIO_MEM; |
559 | uart->port.flags = UPF_BOOT_AUTOCONF; | 574 | uart->port.flags = UPF_BOOT_AUTOCONF; |
560 | uart->port.line = pdev->id; | 575 | uart->port.line = dev_id; |
561 | uart->port.ops = &arc_serial_pops; | 576 | uart->port.ops = &arc_serial_pops; |
562 | 577 | ||
563 | uart->port.uartclk = plat_data[1]; | ||
564 | uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; | 578 | uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; |
565 | 579 | ||
566 | /* | 580 | /* |
@@ -569,9 +583,6 @@ arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | |||
569 | */ | 583 | */ |
570 | uart->port.ignore_status_mask = 0; | 584 | uart->port.ignore_status_mask = 0; |
571 | 585 | ||
572 | /* Real Hardware vs. emulated to work around a bug */ | ||
573 | uart->is_emulated = !!plat_data[2]; | ||
574 | |||
575 | return 0; | 586 | return 0; |
576 | } | 587 | } |
577 | 588 | ||
@@ -648,45 +659,50 @@ static __init void early_serial_write(struct console *con, const char *s, | |||
648 | } | 659 | } |
649 | } | 660 | } |
650 | 661 | ||
651 | static struct __initdata console arc_early_serial_console = { | 662 | static struct console arc_early_serial_console __initdata = { |
652 | .name = "early_ARCuart", | 663 | .name = "early_ARCuart", |
653 | .write = early_serial_write, | 664 | .write = early_serial_write, |
654 | .flags = CON_PRINTBUFFER | CON_BOOT, | 665 | .flags = CON_PRINTBUFFER | CON_BOOT, |
655 | .index = -1 | 666 | .index = -1 |
656 | }; | 667 | }; |
657 | 668 | ||
658 | static int arc_serial_probe_earlyprintk(struct platform_device *pdev) | 669 | static int __init arc_serial_probe_earlyprintk(struct platform_device *pdev) |
659 | { | 670 | { |
660 | arc_early_serial_console.index = pdev->id; | 671 | int dev_id = pdev->id < 0 ? 0 : pdev->id; |
672 | int rc; | ||
673 | |||
674 | arc_early_serial_console.index = dev_id; | ||
661 | 675 | ||
662 | arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]); | 676 | rc = arc_uart_init_one(pdev, dev_id); |
677 | if (rc) | ||
678 | panic("early console init failed\n"); | ||
663 | 679 | ||
664 | arc_serial_console_setup(&arc_early_serial_console, NULL); | 680 | arc_serial_console_setup(&arc_early_serial_console, NULL); |
665 | 681 | ||
666 | register_console(&arc_early_serial_console); | 682 | register_console(&arc_early_serial_console); |
667 | return 0; | 683 | return 0; |
668 | } | 684 | } |
669 | #else | ||
670 | static int arc_serial_probe_earlyprintk(struct platform_device *pdev) | ||
671 | { | ||
672 | return -ENODEV; | ||
673 | } | ||
674 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | 685 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ |
675 | 686 | ||
676 | static int arc_serial_probe(struct platform_device *pdev) | 687 | static int arc_serial_probe(struct platform_device *pdev) |
677 | { | 688 | { |
678 | struct arc_uart_port *uart; | 689 | int rc, dev_id; |
679 | int rc; | 690 | struct device_node *np = pdev->dev.of_node; |
691 | |||
692 | /* no device tree device */ | ||
693 | if (!np) | ||
694 | return -ENODEV; | ||
680 | 695 | ||
681 | if (is_early_platform_device(pdev)) | 696 | dev_id = of_alias_get_id(np, "serial"); |
682 | return arc_serial_probe_earlyprintk(pdev); | 697 | if (dev_id < 0) |
698 | dev_id = 0; | ||
683 | 699 | ||
684 | uart = &arc_uart_ports[pdev->id]; | 700 | rc = arc_uart_init_one(pdev, dev_id); |
685 | rc = arc_uart_init_one(pdev, uart); | ||
686 | if (rc) | 701 | if (rc) |
687 | return rc; | 702 | return rc; |
688 | 703 | ||
689 | return uart_add_one_port(&arc_uart_driver, &uart->port); | 704 | rc = uart_add_one_port(&arc_uart_driver, &arc_uart_ports[dev_id].port); |
705 | return rc; | ||
690 | } | 706 | } |
691 | 707 | ||
692 | static int arc_serial_remove(struct platform_device *pdev) | 708 | static int arc_serial_remove(struct platform_device *pdev) |
@@ -695,16 +711,32 @@ static int arc_serial_remove(struct platform_device *pdev) | |||
695 | return 0; | 711 | return 0; |
696 | } | 712 | } |
697 | 713 | ||
714 | static const struct of_device_id arc_uart_dt_ids[] = { | ||
715 | { .compatible = "snps,arc-uart" }, | ||
716 | { /* Sentinel */ } | ||
717 | }; | ||
718 | MODULE_DEVICE_TABLE(of, arc_uart_dt_ids); | ||
719 | |||
698 | static struct platform_driver arc_platform_driver = { | 720 | static struct platform_driver arc_platform_driver = { |
699 | .probe = arc_serial_probe, | 721 | .probe = arc_serial_probe, |
700 | .remove = arc_serial_remove, | 722 | .remove = arc_serial_remove, |
701 | .driver = { | 723 | .driver = { |
702 | .name = DRIVER_NAME, | 724 | .name = DRIVER_NAME, |
703 | .owner = THIS_MODULE, | 725 | .owner = THIS_MODULE, |
726 | .of_match_table = arc_uart_dt_ids, | ||
704 | }, | 727 | }, |
705 | }; | 728 | }; |
706 | 729 | ||
707 | #ifdef CONFIG_SERIAL_ARC_CONSOLE | 730 | #ifdef CONFIG_SERIAL_ARC_CONSOLE |
731 | |||
732 | static struct platform_driver early_arc_platform_driver __initdata = { | ||
733 | .probe = arc_serial_probe_earlyprintk, | ||
734 | .remove = arc_serial_remove, | ||
735 | .driver = { | ||
736 | .name = DRIVER_NAME, | ||
737 | .owner = THIS_MODULE, | ||
738 | }, | ||
739 | }; | ||
708 | /* | 740 | /* |
709 | * Register an early platform driver of "earlyprintk" class. | 741 | * Register an early platform driver of "earlyprintk" class. |
710 | * ARCH platform code installs the driver and probes the early devices | 742 | * ARCH platform code installs the driver and probes the early devices |
@@ -712,7 +744,7 @@ static struct platform_driver arc_platform_driver = { | |||
712 | * or it could be done independently, for all "earlyprintk" class drivers. | 744 | * or it could be done independently, for all "earlyprintk" class drivers. |
713 | * [see arch/arc/plat-arcfpga/platform.c] | 745 | * [see arch/arc/plat-arcfpga/platform.c] |
714 | */ | 746 | */ |
715 | early_platform_init("earlyprintk", &arc_platform_driver); | 747 | early_platform_init("earlyprintk", &early_arc_platform_driver); |
716 | 748 | ||
717 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | 749 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ |
718 | 750 | ||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 922e85aeb63a..d4a7c241b751 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -774,14 +774,14 @@ static void atmel_rx_from_ring(struct uart_port *port) | |||
774 | * uart_start(), which takes the lock. | 774 | * uart_start(), which takes the lock. |
775 | */ | 775 | */ |
776 | spin_unlock(&port->lock); | 776 | spin_unlock(&port->lock); |
777 | tty_flip_buffer_push(port->state->port.tty); | 777 | tty_flip_buffer_push(&port->state->port); |
778 | spin_lock(&port->lock); | 778 | spin_lock(&port->lock); |
779 | } | 779 | } |
780 | 780 | ||
781 | static void atmel_rx_from_dma(struct uart_port *port) | 781 | static void atmel_rx_from_dma(struct uart_port *port) |
782 | { | 782 | { |
783 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 783 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
784 | struct tty_struct *tty = port->state->port.tty; | 784 | struct tty_port *tport = &port->state->port; |
785 | struct atmel_dma_buffer *pdc; | 785 | struct atmel_dma_buffer *pdc; |
786 | int rx_idx = atmel_port->pdc_rx_idx; | 786 | int rx_idx = atmel_port->pdc_rx_idx; |
787 | unsigned int head; | 787 | unsigned int head; |
@@ -820,7 +820,8 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
820 | */ | 820 | */ |
821 | count = head - tail; | 821 | count = head - tail; |
822 | 822 | ||
823 | tty_insert_flip_string(tty, pdc->buf + pdc->ofs, count); | 823 | tty_insert_flip_string(tport, pdc->buf + pdc->ofs, |
824 | count); | ||
824 | 825 | ||
825 | dma_sync_single_for_device(port->dev, pdc->dma_addr, | 826 | dma_sync_single_for_device(port->dev, pdc->dma_addr, |
826 | pdc->dma_size, DMA_FROM_DEVICE); | 827 | pdc->dma_size, DMA_FROM_DEVICE); |
@@ -848,7 +849,7 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
848 | * uart_start(), which takes the lock. | 849 | * uart_start(), which takes the lock. |
849 | */ | 850 | */ |
850 | spin_unlock(&port->lock); | 851 | spin_unlock(&port->lock); |
851 | tty_flip_buffer_push(tty); | 852 | tty_flip_buffer_push(tport); |
852 | spin_lock(&port->lock); | 853 | spin_lock(&port->lock); |
853 | 854 | ||
854 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); | 855 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); |
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index c76a226080f2..719594e5fc21 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c | |||
@@ -235,14 +235,13 @@ static const char *bcm_uart_type(struct uart_port *port) | |||
235 | */ | 235 | */ |
236 | static void bcm_uart_do_rx(struct uart_port *port) | 236 | static void bcm_uart_do_rx(struct uart_port *port) |
237 | { | 237 | { |
238 | struct tty_struct *tty; | 238 | struct tty_port *port = &port->state->port; |
239 | unsigned int max_count; | 239 | unsigned int max_count; |
240 | 240 | ||
241 | /* limit number of char read in interrupt, should not be | 241 | /* limit number of char read in interrupt, should not be |
242 | * higher than fifo size anyway since we're much faster than | 242 | * higher than fifo size anyway since we're much faster than |
243 | * serial port */ | 243 | * serial port */ |
244 | max_count = 32; | 244 | max_count = 32; |
245 | tty = port->state->port.tty; | ||
246 | do { | 245 | do { |
247 | unsigned int iestat, c, cstat; | 246 | unsigned int iestat, c, cstat; |
248 | char flag; | 247 | char flag; |
@@ -261,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port) | |||
261 | bcm_uart_writel(port, val, UART_CTL_REG); | 260 | bcm_uart_writel(port, val, UART_CTL_REG); |
262 | 261 | ||
263 | port->icount.overrun++; | 262 | port->icount.overrun++; |
264 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 263 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
265 | } | 264 | } |
266 | 265 | ||
267 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) | 266 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) |
@@ -300,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port) | |||
300 | 299 | ||
301 | 300 | ||
302 | if ((cstat & port->ignore_status_mask) == 0) | 301 | if ((cstat & port->ignore_status_mask) == 0) |
303 | tty_insert_flip_char(tty, c, flag); | 302 | tty_insert_flip_char(port, c, flag); |
304 | 303 | ||
305 | } while (--max_count); | 304 | } while (--max_count); |
306 | 305 | ||
307 | tty_flip_buffer_push(tty); | 306 | tty_flip_buffer_push(port); |
308 | } | 307 | } |
309 | 308 | ||
310 | /* | 309 | /* |
diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index f5d117379b60..487c173b0f72 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c | |||
@@ -149,7 +149,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate) | |||
149 | static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | 149 | static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) |
150 | { | 150 | { |
151 | struct sport_uart_port *up = dev_id; | 151 | struct sport_uart_port *up = dev_id; |
152 | struct tty_struct *tty = up->port.state->port.tty; | 152 | struct tty_port *port = &up->port.state->port; |
153 | unsigned int ch; | 153 | unsigned int ch; |
154 | 154 | ||
155 | spin_lock(&up->port.lock); | 155 | spin_lock(&up->port.lock); |
@@ -159,9 +159,10 @@ static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | |||
159 | up->port.icount.rx++; | 159 | up->port.icount.rx++; |
160 | 160 | ||
161 | if (!uart_handle_sysrq_char(&up->port, ch)) | 161 | if (!uart_handle_sysrq_char(&up->port, ch)) |
162 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 162 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
163 | } | 163 | } |
164 | tty_flip_buffer_push(tty); | 164 | /* XXX this won't deadlock with lowlat? */ |
165 | tty_flip_buffer_push(port); | ||
165 | 166 | ||
166 | spin_unlock(&up->port.lock); | 167 | spin_unlock(&up->port.lock); |
167 | 168 | ||
@@ -182,7 +183,6 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) | |||
182 | static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | 183 | static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) |
183 | { | 184 | { |
184 | struct sport_uart_port *up = dev_id; | 185 | struct sport_uart_port *up = dev_id; |
185 | struct tty_struct *tty = up->port.state->port.tty; | ||
186 | unsigned int stat = SPORT_GET_STAT(up); | 186 | unsigned int stat = SPORT_GET_STAT(up); |
187 | 187 | ||
188 | spin_lock(&up->port.lock); | 188 | spin_lock(&up->port.lock); |
@@ -190,7 +190,7 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
190 | /* Overflow in RX FIFO */ | 190 | /* Overflow in RX FIFO */ |
191 | if (stat & ROVF) { | 191 | if (stat & ROVF) { |
192 | up->port.icount.overrun++; | 192 | up->port.icount.overrun++; |
193 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 193 | tty_insert_flip_char(&up->port.state->port, 0, TTY_OVERRUN); |
194 | SPORT_PUT_STAT(up, ROVF); /* Clear ROVF bit */ | 194 | SPORT_PUT_STAT(up, ROVF); /* Clear ROVF bit */ |
195 | } | 195 | } |
196 | /* These should not happen */ | 196 | /* These should not happen */ |
@@ -205,6 +205,8 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
205 | SSYNC(); | 205 | SSYNC(); |
206 | 206 | ||
207 | spin_unlock(&up->port.lock); | 207 | spin_unlock(&up->port.lock); |
208 | /* XXX we don't push the overrun bit to TTY? */ | ||
209 | |||
208 | return IRQ_HANDLED; | 210 | return IRQ_HANDLED; |
209 | } | 211 | } |
210 | 212 | ||
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 2e2b2c1cb722..12dceda9db33 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -223,7 +223,6 @@ static void bfin_serial_enable_ms(struct uart_port *port) | |||
223 | #ifdef CONFIG_SERIAL_BFIN_PIO | 223 | #ifdef CONFIG_SERIAL_BFIN_PIO |
224 | static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | 224 | static void bfin_serial_rx_chars(struct bfin_serial_port *uart) |
225 | { | 225 | { |
226 | struct tty_struct *tty = NULL; | ||
227 | unsigned int status, ch, flg; | 226 | unsigned int status, ch, flg; |
228 | static struct timeval anomaly_start = { .tv_sec = 0 }; | 227 | static struct timeval anomaly_start = { .tv_sec = 0 }; |
229 | 228 | ||
@@ -242,11 +241,9 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
242 | return; | 241 | return; |
243 | } | 242 | } |
244 | 243 | ||
245 | if (!uart->port.state || !uart->port.state->port.tty) | 244 | if (!uart->port.state) |
246 | return; | 245 | return; |
247 | #endif | 246 | #endif |
248 | tty = uart->port.state->port.tty; | ||
249 | |||
250 | if (ANOMALY_05000363) { | 247 | if (ANOMALY_05000363) { |
251 | /* The BF533 (and BF561) family of processors have a nice anomaly | 248 | /* The BF533 (and BF561) family of processors have a nice anomaly |
252 | * where they continuously generate characters for a "single" break. | 249 | * where they continuously generate characters for a "single" break. |
@@ -325,7 +322,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
325 | uart_insert_char(&uart->port, status, OE, ch, flg); | 322 | uart_insert_char(&uart->port, status, OE, ch, flg); |
326 | 323 | ||
327 | ignore_char: | 324 | ignore_char: |
328 | tty_flip_buffer_push(tty); | 325 | tty_flip_buffer_push(&uart->port.state->port); |
329 | } | 326 | } |
330 | 327 | ||
331 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | 328 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) |
@@ -426,7 +423,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
426 | 423 | ||
427 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | 424 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) |
428 | { | 425 | { |
429 | struct tty_struct *tty = uart->port.state->port.tty; | ||
430 | int i, flg, status; | 426 | int i, flg, status; |
431 | 427 | ||
432 | status = UART_GET_LSR(uart); | 428 | status = UART_GET_LSR(uart); |
@@ -471,7 +467,7 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | |||
471 | } | 467 | } |
472 | 468 | ||
473 | dma_ignore_char: | 469 | dma_ignore_char: |
474 | tty_flip_buffer_push(tty); | 470 | tty_flip_buffer_push(&uart->port.state->port); |
475 | } | 471 | } |
476 | 472 | ||
477 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | 473 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) |
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 3fd2526d121e..bfb17968c8db 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -85,12 +85,8 @@ static void uart_clps711x_enable_ms(struct uart_port *port) | |||
85 | static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) | 85 | static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) |
86 | { | 86 | { |
87 | struct uart_port *port = dev_id; | 87 | struct uart_port *port = dev_id; |
88 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
89 | unsigned int status, ch, flg; | 88 | unsigned int status, ch, flg; |
90 | 89 | ||
91 | if (!tty) | ||
92 | return IRQ_HANDLED; | ||
93 | |||
94 | for (;;) { | 90 | for (;;) { |
95 | status = clps_readl(SYSFLG(port)); | 91 | status = clps_readl(SYSFLG(port)); |
96 | if (status & SYSFLG_URXFE) | 92 | if (status & SYSFLG_URXFE) |
@@ -130,9 +126,7 @@ static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) | |||
130 | uart_insert_char(port, status, UARTDR_OVERR, ch, flg); | 126 | uart_insert_char(port, status, UARTDR_OVERR, ch, flg); |
131 | } | 127 | } |
132 | 128 | ||
133 | tty_flip_buffer_push(tty); | 129 | tty_flip_buffer_push(&port->state->port); |
134 | |||
135 | tty_kref_put(tty); | ||
136 | 130 | ||
137 | return IRQ_HANDLED; | 131 | return IRQ_HANDLED; |
138 | } | 132 | } |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index ad0caf176808..97f4e1858649 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c | |||
@@ -245,7 +245,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
245 | int i; | 245 | int i; |
246 | unsigned char ch; | 246 | unsigned char ch; |
247 | u8 *cp; | 247 | u8 *cp; |
248 | struct tty_struct *tty = port->state->port.tty; | 248 | struct tty_port *tport = &port->state->port; |
249 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 249 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
250 | cbd_t __iomem *bdp; | 250 | cbd_t __iomem *bdp; |
251 | u16 status; | 251 | u16 status; |
@@ -276,7 +276,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
276 | /* If we have not enough room in tty flip buffer, then we try | 276 | /* If we have not enough room in tty flip buffer, then we try |
277 | * later, which will be the next rx-interrupt or a timeout | 277 | * later, which will be the next rx-interrupt or a timeout |
278 | */ | 278 | */ |
279 | if(tty_buffer_request_room(tty, i) < i) { | 279 | if (tty_buffer_request_room(tport, i) < i) { |
280 | printk(KERN_WARNING "No room in flip buffer\n"); | 280 | printk(KERN_WARNING "No room in flip buffer\n"); |
281 | return; | 281 | return; |
282 | } | 282 | } |
@@ -302,7 +302,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
302 | } | 302 | } |
303 | #endif | 303 | #endif |
304 | error_return: | 304 | error_return: |
305 | tty_insert_flip_char(tty, ch, flg); | 305 | tty_insert_flip_char(tport, ch, flg); |
306 | 306 | ||
307 | } /* End while (i--) */ | 307 | } /* End while (i--) */ |
308 | 308 | ||
@@ -322,7 +322,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
322 | pinfo->rx_cur = bdp; | 322 | pinfo->rx_cur = bdp; |
323 | 323 | ||
324 | /* activate BH processing */ | 324 | /* activate BH processing */ |
325 | tty_flip_buffer_push(tty); | 325 | tty_flip_buffer_push(tport); |
326 | 326 | ||
327 | return; | 327 | return; |
328 | 328 | ||
@@ -507,7 +507,7 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
507 | 507 | ||
508 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | 508 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); |
509 | if (baud < HW_BUF_SPD_THRESHOLD || | 509 | if (baud < HW_BUF_SPD_THRESHOLD || |
510 | (pinfo->port.state && pinfo->port.state->port.tty->low_latency)) | 510 | (pinfo->port.state && pinfo->port.state->port.low_latency)) |
511 | pinfo->rx_fifosize = 1; | 511 | pinfo->rx_fifosize = 1; |
512 | else | 512 | else |
513 | pinfo->rx_fifosize = RX_BUF_SIZE; | 513 | pinfo->rx_fifosize = RX_BUF_SIZE; |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 35ee6a2c6877..5f37c31e32bc 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -1760,8 +1760,7 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl | |||
1760 | 1760 | ||
1761 | info->icount.rx++; | 1761 | info->icount.rx++; |
1762 | } else { | 1762 | } else { |
1763 | struct tty_struct *tty = info->port.tty; | 1763 | tty_insert_flip_char(&info->port, data, flag); |
1764 | tty_insert_flip_char(tty, data, flag); | ||
1765 | info->icount.rx++; | 1764 | info->icount.rx++; |
1766 | } | 1765 | } |
1767 | 1766 | ||
@@ -2105,22 +2104,15 @@ static int force_eop_if_needed(struct e100_serial *info) | |||
2105 | 2104 | ||
2106 | static void flush_to_flip_buffer(struct e100_serial *info) | 2105 | static void flush_to_flip_buffer(struct e100_serial *info) |
2107 | { | 2106 | { |
2108 | struct tty_struct *tty; | ||
2109 | struct etrax_recv_buffer *buffer; | 2107 | struct etrax_recv_buffer *buffer; |
2110 | unsigned long flags; | 2108 | unsigned long flags; |
2111 | 2109 | ||
2112 | local_irq_save(flags); | 2110 | local_irq_save(flags); |
2113 | tty = info->port.tty; | ||
2114 | |||
2115 | if (!tty) { | ||
2116 | local_irq_restore(flags); | ||
2117 | return; | ||
2118 | } | ||
2119 | 2111 | ||
2120 | while ((buffer = info->first_recv_buffer) != NULL) { | 2112 | while ((buffer = info->first_recv_buffer) != NULL) { |
2121 | unsigned int count = buffer->length; | 2113 | unsigned int count = buffer->length; |
2122 | 2114 | ||
2123 | tty_insert_flip_string(tty, buffer->buffer, count); | 2115 | tty_insert_flip_string(&info->port, buffer->buffer, count); |
2124 | info->recv_cnt -= count; | 2116 | info->recv_cnt -= count; |
2125 | 2117 | ||
2126 | if (count == buffer->length) { | 2118 | if (count == buffer->length) { |
@@ -2139,7 +2131,7 @@ static void flush_to_flip_buffer(struct e100_serial *info) | |||
2139 | local_irq_restore(flags); | 2131 | local_irq_restore(flags); |
2140 | 2132 | ||
2141 | /* This includes a check for low-latency */ | 2133 | /* This includes a check for low-latency */ |
2142 | tty_flip_buffer_push(tty); | 2134 | tty_flip_buffer_push(&info->port); |
2143 | } | 2135 | } |
2144 | 2136 | ||
2145 | static void check_flush_timeout(struct e100_serial *info) | 2137 | static void check_flush_timeout(struct e100_serial *info) |
@@ -2275,12 +2267,6 @@ static | |||
2275 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) | 2267 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) |
2276 | { | 2268 | { |
2277 | unsigned long data_read; | 2269 | unsigned long data_read; |
2278 | struct tty_struct *tty = info->port.tty; | ||
2279 | |||
2280 | if (!tty) { | ||
2281 | printk("!NO TTY!\n"); | ||
2282 | return info; | ||
2283 | } | ||
2284 | 2270 | ||
2285 | /* Read data and status at the same time */ | 2271 | /* Read data and status at the same time */ |
2286 | data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); | 2272 | data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); |
@@ -2338,8 +2324,7 @@ more_data: | |||
2338 | data_in, data_read); | 2324 | data_in, data_read); |
2339 | char flag = TTY_NORMAL; | 2325 | char flag = TTY_NORMAL; |
2340 | if (info->errorcode == ERRCODE_INSERT_BREAK) { | 2326 | if (info->errorcode == ERRCODE_INSERT_BREAK) { |
2341 | struct tty_struct *tty = info->port.tty; | 2327 | tty_insert_flip_char(&info->port, 0, flag); |
2342 | tty_insert_flip_char(tty, 0, flag); | ||
2343 | info->icount.rx++; | 2328 | info->icount.rx++; |
2344 | } | 2329 | } |
2345 | 2330 | ||
@@ -2353,7 +2338,7 @@ more_data: | |||
2353 | info->icount.frame++; | 2338 | info->icount.frame++; |
2354 | flag = TTY_FRAME; | 2339 | flag = TTY_FRAME; |
2355 | } | 2340 | } |
2356 | tty_insert_flip_char(tty, data, flag); | 2341 | tty_insert_flip_char(&info->port, data, flag); |
2357 | info->errorcode = 0; | 2342 | info->errorcode = 0; |
2358 | } | 2343 | } |
2359 | info->break_detected_cnt = 0; | 2344 | info->break_detected_cnt = 0; |
@@ -2369,7 +2354,7 @@ more_data: | |||
2369 | log_int(rdpc(), 0, 0); | 2354 | log_int(rdpc(), 0, 0); |
2370 | } | 2355 | } |
2371 | ); | 2356 | ); |
2372 | tty_insert_flip_char(tty, | 2357 | tty_insert_flip_char(&info->port, |
2373 | IO_EXTRACT(R_SERIAL0_READ, data_in, data_read), | 2358 | IO_EXTRACT(R_SERIAL0_READ, data_in, data_read), |
2374 | TTY_NORMAL); | 2359 | TTY_NORMAL); |
2375 | } else { | 2360 | } else { |
@@ -2384,7 +2369,7 @@ more_data: | |||
2384 | goto more_data; | 2369 | goto more_data; |
2385 | } | 2370 | } |
2386 | 2371 | ||
2387 | tty_flip_buffer_push(info->port.tty); | 2372 | tty_flip_buffer_push(&info->port); |
2388 | return info; | 2373 | return info; |
2389 | } | 2374 | } |
2390 | 2375 | ||
@@ -3137,7 +3122,7 @@ static int rs_raw_write(struct tty_struct *tty, | |||
3137 | 3122 | ||
3138 | /* first some sanity checks */ | 3123 | /* first some sanity checks */ |
3139 | 3124 | ||
3140 | if (!tty || !info->xmit.buf) | 3125 | if (!info->xmit.buf) |
3141 | return 0; | 3126 | return 0; |
3142 | 3127 | ||
3143 | #ifdef SERIAL_DEBUG_DATA | 3128 | #ifdef SERIAL_DEBUG_DATA |
@@ -3464,7 +3449,7 @@ set_serial_info(struct e100_serial *info, | |||
3464 | info->type = new_serial.type; | 3449 | info->type = new_serial.type; |
3465 | info->close_delay = new_serial.close_delay; | 3450 | info->close_delay = new_serial.close_delay; |
3466 | info->closing_wait = new_serial.closing_wait; | 3451 | info->closing_wait = new_serial.closing_wait; |
3467 | info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 3452 | info->port.low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
3468 | 3453 | ||
3469 | check_and_exit: | 3454 | check_and_exit: |
3470 | if (info->flags & ASYNC_INITIALIZED) { | 3455 | if (info->flags & ASYNC_INITIALIZED) { |
@@ -4108,7 +4093,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4108 | tty->driver_data = info; | 4093 | tty->driver_data = info; |
4109 | info->port.tty = tty; | 4094 | info->port.tty = tty; |
4110 | 4095 | ||
4111 | tty->low_latency = !!(info->flags & ASYNC_LOW_LATENCY); | 4096 | info->port.low_latency = !!(info->flags & ASYNC_LOW_LATENCY); |
4112 | 4097 | ||
4113 | /* | 4098 | /* |
4114 | * If the port is in the middle of closing, bail out now | 4099 | * If the port is in the middle of closing, bail out now |
diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 6491b8644a7f..2f2b2e538a54 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c | |||
@@ -187,7 +187,6 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
187 | { | 187 | { |
188 | struct uart_port *uport; | 188 | struct uart_port *uport; |
189 | struct dz_port *dport = &mux->dport[0]; | 189 | struct dz_port *dport = &mux->dport[0]; |
190 | struct tty_struct *tty = NULL; | ||
191 | struct uart_icount *icount; | 190 | struct uart_icount *icount; |
192 | int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; | 191 | int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; |
193 | unsigned char ch, flag; | 192 | unsigned char ch, flag; |
@@ -197,7 +196,6 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
197 | while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { | 196 | while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { |
198 | dport = &mux->dport[LINE(status)]; | 197 | dport = &mux->dport[LINE(status)]; |
199 | uport = &dport->port; | 198 | uport = &dport->port; |
200 | tty = uport->state->port.tty; /* point to the proper dev */ | ||
201 | 199 | ||
202 | ch = UCHAR(status); /* grab the char */ | 200 | ch = UCHAR(status); /* grab the char */ |
203 | flag = TTY_NORMAL; | 201 | flag = TTY_NORMAL; |
@@ -249,7 +247,7 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
249 | } | 247 | } |
250 | for (i = 0; i < DZ_NB_PORT; i++) | 248 | for (i = 0; i < DZ_NB_PORT; i++) |
251 | if (lines_rx[i]) | 249 | if (lines_rx[i]) |
252 | tty_flip_buffer_push(mux->dport[i].port.state->port.tty); | 250 | tty_flip_buffer_push(&mux->dport[i].port.state->port); |
253 | } | 251 | } |
254 | 252 | ||
255 | /* | 253 | /* |
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index a8cbb2670521..7d199c8e1a75 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c | |||
@@ -81,6 +81,7 @@ struct efm32_uart_port { | |||
81 | struct uart_port port; | 81 | struct uart_port port; |
82 | unsigned int txirq; | 82 | unsigned int txirq; |
83 | struct clk *clk; | 83 | struct clk *clk; |
84 | struct efm32_uart_pdata pdata; | ||
84 | }; | 85 | }; |
85 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) | 86 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) |
86 | #define efm_debug(efm_port, format, arg...) \ | 87 | #define efm_debug(efm_port, format, arg...) \ |
@@ -194,8 +195,7 @@ static void efm32_uart_break_ctl(struct uart_port *port, int ctl) | |||
194 | /* not possible without fiddling with gpios */ | 195 | /* not possible without fiddling with gpios */ |
195 | } | 196 | } |
196 | 197 | ||
197 | static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, | 198 | static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port) |
198 | struct tty_struct *tty) | ||
199 | { | 199 | { |
200 | struct uart_port *port = &efm_port->port; | 200 | struct uart_port *port = &efm_port->port; |
201 | 201 | ||
@@ -237,8 +237,8 @@ static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, | |||
237 | rxdata & UARTn_RXDATAX_RXDATA__MASK)) | 237 | rxdata & UARTn_RXDATAX_RXDATA__MASK)) |
238 | continue; | 238 | continue; |
239 | 239 | ||
240 | if (tty && (rxdata & port->ignore_status_mask) == 0) | 240 | if ((rxdata & port->ignore_status_mask) == 0) |
241 | tty_insert_flip_char(tty, | 241 | tty_insert_flip_char(&port->state->port, |
242 | rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); | 242 | rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); |
243 | } | 243 | } |
244 | } | 244 | } |
@@ -249,15 +249,13 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) | |||
249 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); | 249 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); |
250 | int handled = IRQ_NONE; | 250 | int handled = IRQ_NONE; |
251 | struct uart_port *port = &efm_port->port; | 251 | struct uart_port *port = &efm_port->port; |
252 | struct tty_struct *tty; | 252 | struct tty_port *tport = &port->state->port; |
253 | 253 | ||
254 | spin_lock(&port->lock); | 254 | spin_lock(&port->lock); |
255 | 255 | ||
256 | tty = tty_kref_get(port->state->port.tty); | ||
257 | |||
258 | if (irqflag & UARTn_IF_RXDATAV) { | 256 | if (irqflag & UARTn_IF_RXDATAV) { |
259 | efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); | 257 | efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); |
260 | efm32_uart_rx_chars(efm_port, tty); | 258 | efm32_uart_rx_chars(efm_port); |
261 | 259 | ||
262 | handled = IRQ_HANDLED; | 260 | handled = IRQ_HANDLED; |
263 | } | 261 | } |
@@ -265,16 +263,12 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) | |||
265 | if (irqflag & UARTn_IF_RXOF) { | 263 | if (irqflag & UARTn_IF_RXOF) { |
266 | efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); | 264 | efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); |
267 | port->icount.overrun++; | 265 | port->icount.overrun++; |
268 | if (tty) | 266 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
269 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
270 | 267 | ||
271 | handled = IRQ_HANDLED; | 268 | handled = IRQ_HANDLED; |
272 | } | 269 | } |
273 | 270 | ||
274 | if (tty) { | 271 | tty_flip_buffer_push(tport); |
275 | tty_flip_buffer_push(tty); | ||
276 | tty_kref_put(tty); | ||
277 | } | ||
278 | 272 | ||
279 | spin_unlock(&port->lock); | 273 | spin_unlock(&port->lock); |
280 | 274 | ||
@@ -300,13 +294,8 @@ static irqreturn_t efm32_uart_txirq(int irq, void *data) | |||
300 | static int efm32_uart_startup(struct uart_port *port) | 294 | static int efm32_uart_startup(struct uart_port *port) |
301 | { | 295 | { |
302 | struct efm32_uart_port *efm_port = to_efm_port(port); | 296 | struct efm32_uart_port *efm_port = to_efm_port(port); |
303 | u32 location = 0; | ||
304 | struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); | ||
305 | int ret; | 297 | int ret; |
306 | 298 | ||
307 | if (pdata) | ||
308 | location = UARTn_ROUTE_LOCATION(pdata->location); | ||
309 | |||
310 | ret = clk_enable(efm_port->clk); | 299 | ret = clk_enable(efm_port->clk); |
311 | if (ret) { | 300 | if (ret) { |
312 | efm_debug(efm_port, "failed to enable clk\n"); | 301 | efm_debug(efm_port, "failed to enable clk\n"); |
@@ -315,7 +304,9 @@ static int efm32_uart_startup(struct uart_port *port) | |||
315 | port->uartclk = clk_get_rate(efm_port->clk); | 304 | port->uartclk = clk_get_rate(efm_port->clk); |
316 | 305 | ||
317 | /* Enable pins at configured location */ | 306 | /* Enable pins at configured location */ |
318 | efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | 307 | efm32_uart_write32(efm_port, |
308 | UARTn_ROUTE_LOCATION(efm_port->pdata.location) | | ||
309 | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | ||
319 | UARTn_ROUTE); | 310 | UARTn_ROUTE); |
320 | 311 | ||
321 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, | 312 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, |
@@ -674,11 +665,24 @@ static int efm32_uart_probe_dt(struct platform_device *pdev, | |||
674 | struct efm32_uart_port *efm_port) | 665 | struct efm32_uart_port *efm_port) |
675 | { | 666 | { |
676 | struct device_node *np = pdev->dev.of_node; | 667 | struct device_node *np = pdev->dev.of_node; |
668 | u32 location; | ||
677 | int ret; | 669 | int ret; |
678 | 670 | ||
679 | if (!np) | 671 | if (!np) |
680 | return 1; | 672 | return 1; |
681 | 673 | ||
674 | ret = of_property_read_u32(np, "location", &location); | ||
675 | if (!ret) { | ||
676 | if (location > 5) { | ||
677 | dev_err(&pdev->dev, "invalid location\n"); | ||
678 | return -EINVAL; | ||
679 | } | ||
680 | efm_debug(efm_port, "using location %u\n", location); | ||
681 | efm_port->pdata.location = location; | ||
682 | } else { | ||
683 | efm_debug(efm_port, "fall back to location 0\n"); | ||
684 | } | ||
685 | |||
682 | ret = of_alias_get_id(np, "serial"); | 686 | ret = of_alias_get_id(np, "serial"); |
683 | if (ret < 0) { | 687 | if (ret < 0) { |
684 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); | 688 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); |
@@ -738,10 +742,16 @@ static int efm32_uart_probe(struct platform_device *pdev) | |||
738 | efm_port->port.flags = UPF_BOOT_AUTOCONF; | 742 | efm_port->port.flags = UPF_BOOT_AUTOCONF; |
739 | 743 | ||
740 | ret = efm32_uart_probe_dt(pdev, efm_port); | 744 | ret = efm32_uart_probe_dt(pdev, efm_port); |
741 | if (ret > 0) | 745 | if (ret > 0) { |
742 | /* not created by device tree */ | 746 | /* not created by device tree */ |
747 | const struct efm32_uart_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
748 | |||
743 | efm_port->port.line = pdev->id; | 749 | efm_port->port.line = pdev->id; |
744 | 750 | ||
751 | if (pdata) | ||
752 | efm_port->pdata = *pdata; | ||
753 | } | ||
754 | |||
745 | if (efm_port->port.line >= 0 && | 755 | if (efm_port->port.line >= 0 && |
746 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) | 756 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) |
747 | efm32_uart_ports[efm_port->port.line] = efm_port; | 757 | efm32_uart_ports[efm_port->port.line] = efm_port; |
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 72b6334bcf1a..bc9e6b017b05 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c | |||
@@ -734,7 +734,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
734 | static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | 734 | static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) |
735 | { | 735 | { |
736 | short int count, rcv_buff; | 736 | short int count, rcv_buff; |
737 | struct tty_struct *tty = icom_port->uart_port.state->port.tty; | 737 | struct tty_port *port = &icom_port->uart_port.state->port; |
738 | unsigned short int status; | 738 | unsigned short int status; |
739 | struct uart_icount *icount; | 739 | struct uart_icount *icount; |
740 | unsigned long offset; | 740 | unsigned long offset; |
@@ -761,7 +761,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
761 | /* Block copy all but the last byte as this may have status */ | 761 | /* Block copy all but the last byte as this may have status */ |
762 | if (count > 0) { | 762 | if (count > 0) { |
763 | first = icom_port->recv_buf[offset]; | 763 | first = icom_port->recv_buf[offset]; |
764 | tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1); | 764 | tty_insert_flip_string(port, icom_port->recv_buf + offset, count - 1); |
765 | } | 765 | } |
766 | 766 | ||
767 | icount = &icom_port->uart_port.icount; | 767 | icount = &icom_port->uart_port.icount; |
@@ -812,7 +812,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
812 | 812 | ||
813 | } | 813 | } |
814 | 814 | ||
815 | tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag); | 815 | tty_insert_flip_char(port, *(icom_port->recv_buf + offset + count - 1), flag); |
816 | 816 | ||
817 | if (status & SA_FLAGS_OVERRUN) | 817 | if (status & SA_FLAGS_OVERRUN) |
818 | /* | 818 | /* |
@@ -820,7 +820,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
820 | * reported immediately, and doesn't | 820 | * reported immediately, and doesn't |
821 | * affect the current character | 821 | * affect the current character |
822 | */ | 822 | */ |
823 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 823 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
824 | ignore_char: | 824 | ignore_char: |
825 | icom_port->statStg->rcv[rcv_buff].flags = 0; | 825 | icom_port->statStg->rcv[rcv_buff].flags = 0; |
826 | icom_port->statStg->rcv[rcv_buff].leLength = 0; | 826 | icom_port->statStg->rcv[rcv_buff].leLength = 0; |
@@ -834,7 +834,7 @@ ignore_char: | |||
834 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); | 834 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); |
835 | } | 835 | } |
836 | icom_port->next_rcv = rcv_buff; | 836 | icom_port->next_rcv = rcv_buff; |
837 | tty_flip_buffer_push(tty); | 837 | tty_flip_buffer_push(port); |
838 | } | 838 | } |
839 | 839 | ||
840 | static void process_interrupt(u16 port_int_reg, | 840 | static void process_interrupt(u16 port_int_reg, |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 8cb6d8d66a13..68d7ce997ede 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -481,7 +481,6 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev) | |||
481 | unsigned char *tx_buffer; | 481 | unsigned char *tx_buffer; |
482 | 482 | ||
483 | tx_buffer = ifx_dev->tx_buffer; | 483 | tx_buffer = ifx_dev->tx_buffer; |
484 | memset(tx_buffer, 0, IFX_SPI_TRANSFER_SIZE); | ||
485 | 484 | ||
486 | /* make room for required SPI header */ | 485 | /* make room for required SPI header */ |
487 | tx_buffer += IFX_SPI_HEADER_OVERHEAD; | 486 | tx_buffer += IFX_SPI_HEADER_OVERHEAD; |
@@ -615,7 +614,7 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty) | |||
615 | tty->driver_data = ifx_dev; | 614 | tty->driver_data = ifx_dev; |
616 | 615 | ||
617 | /* allows flip string push from int context */ | 616 | /* allows flip string push from int context */ |
618 | tty->low_latency = 1; | 617 | port->low_latency = 1; |
619 | 618 | ||
620 | /* set flag to allows data transfer */ | 619 | /* set flag to allows data transfer */ |
621 | set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); | 620 | set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); |
@@ -670,12 +669,8 @@ static const struct tty_operations ifx_spi_serial_ops = { | |||
670 | static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, | 669 | static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, |
671 | unsigned char *chars, size_t size) | 670 | unsigned char *chars, size_t size) |
672 | { | 671 | { |
673 | struct tty_struct *tty = tty_port_tty_get(&ifx_dev->tty_port); | 672 | tty_insert_flip_string(&ifx_dev->tty_port, chars, size); |
674 | if (!tty) | 673 | tty_flip_buffer_push(&ifx_dev->tty_port); |
675 | return; | ||
676 | tty_insert_flip_string(tty, chars, size); | ||
677 | tty_flip_buffer_push(tty); | ||
678 | tty_kref_put(tty); | ||
679 | } | 674 | } |
680 | 675 | ||
681 | /** | 676 | /** |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 59819121fe9b..147c9e193595 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -48,8 +48,8 @@ | |||
48 | #include <linux/of.h> | 48 | #include <linux/of.h> |
49 | #include <linux/of_device.h> | 49 | #include <linux/of_device.h> |
50 | #include <linux/pinctrl/consumer.h> | 50 | #include <linux/pinctrl/consumer.h> |
51 | #include <linux/io.h> | ||
51 | 52 | ||
52 | #include <asm/io.h> | ||
53 | #include <asm/irq.h> | 53 | #include <asm/irq.h> |
54 | #include <linux/platform_data/serial-imx.h> | 54 | #include <linux/platform_data/serial-imx.h> |
55 | 55 | ||
@@ -73,102 +73,102 @@ | |||
73 | #define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/ | 73 | #define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/ |
74 | 74 | ||
75 | /* UART Control Register Bit Fields.*/ | 75 | /* UART Control Register Bit Fields.*/ |
76 | #define URXD_CHARRDY (1<<15) | 76 | #define URXD_CHARRDY (1<<15) |
77 | #define URXD_ERR (1<<14) | 77 | #define URXD_ERR (1<<14) |
78 | #define URXD_OVRRUN (1<<13) | 78 | #define URXD_OVRRUN (1<<13) |
79 | #define URXD_FRMERR (1<<12) | 79 | #define URXD_FRMERR (1<<12) |
80 | #define URXD_BRK (1<<11) | 80 | #define URXD_BRK (1<<11) |
81 | #define URXD_PRERR (1<<10) | 81 | #define URXD_PRERR (1<<10) |
82 | #define UCR1_ADEN (1<<15) /* Auto detect interrupt */ | 82 | #define UCR1_ADEN (1<<15) /* Auto detect interrupt */ |
83 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ | 83 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ |
84 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ | 84 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ |
85 | #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ | 85 | #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ |
86 | #define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ | 86 | #define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ |
87 | #define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ | 87 | #define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ |
88 | #define UCR1_IREN (1<<7) /* Infrared interface enable */ | 88 | #define UCR1_IREN (1<<7) /* Infrared interface enable */ |
89 | #define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ | 89 | #define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ |
90 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ | 90 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ |
91 | #define UCR1_SNDBRK (1<<4) /* Send break */ | 91 | #define UCR1_SNDBRK (1<<4) /* Send break */ |
92 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ | 92 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ |
93 | #define IMX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, i.mx1 only */ | 93 | #define IMX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, i.mx1 only */ |
94 | #define UCR1_DOZE (1<<1) /* Doze */ | 94 | #define UCR1_DOZE (1<<1) /* Doze */ |
95 | #define UCR1_UARTEN (1<<0) /* UART enabled */ | 95 | #define UCR1_UARTEN (1<<0) /* UART enabled */ |
96 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ | 96 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ |
97 | #define UCR2_IRTS (1<<14) /* Ignore RTS pin */ | 97 | #define UCR2_IRTS (1<<14) /* Ignore RTS pin */ |
98 | #define UCR2_CTSC (1<<13) /* CTS pin control */ | 98 | #define UCR2_CTSC (1<<13) /* CTS pin control */ |
99 | #define UCR2_CTS (1<<12) /* Clear to send */ | 99 | #define UCR2_CTS (1<<12) /* Clear to send */ |
100 | #define UCR2_ESCEN (1<<11) /* Escape enable */ | 100 | #define UCR2_ESCEN (1<<11) /* Escape enable */ |
101 | #define UCR2_PREN (1<<8) /* Parity enable */ | 101 | #define UCR2_PREN (1<<8) /* Parity enable */ |
102 | #define UCR2_PROE (1<<7) /* Parity odd/even */ | 102 | #define UCR2_PROE (1<<7) /* Parity odd/even */ |
103 | #define UCR2_STPB (1<<6) /* Stop */ | 103 | #define UCR2_STPB (1<<6) /* Stop */ |
104 | #define UCR2_WS (1<<5) /* Word size */ | 104 | #define UCR2_WS (1<<5) /* Word size */ |
105 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ | 105 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ |
106 | #define UCR2_ATEN (1<<3) /* Aging Timer Enable */ | 106 | #define UCR2_ATEN (1<<3) /* Aging Timer Enable */ |
107 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ | 107 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ |
108 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ | 108 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ |
109 | #define UCR2_SRST (1<<0) /* SW reset */ | 109 | #define UCR2_SRST (1<<0) /* SW reset */ |
110 | #define UCR3_DTREN (1<<13) /* DTR interrupt enable */ | 110 | #define UCR3_DTREN (1<<13) /* DTR interrupt enable */ |
111 | #define UCR3_PARERREN (1<<12) /* Parity enable */ | 111 | #define UCR3_PARERREN (1<<12) /* Parity enable */ |
112 | #define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ | 112 | #define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ |
113 | #define UCR3_DSR (1<<10) /* Data set ready */ | 113 | #define UCR3_DSR (1<<10) /* Data set ready */ |
114 | #define UCR3_DCD (1<<9) /* Data carrier detect */ | 114 | #define UCR3_DCD (1<<9) /* Data carrier detect */ |
115 | #define UCR3_RI (1<<8) /* Ring indicator */ | 115 | #define UCR3_RI (1<<8) /* Ring indicator */ |
116 | #define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */ | 116 | #define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */ |
117 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ | 117 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ |
118 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ | 118 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ |
119 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ | 119 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ |
120 | #define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */ | 120 | #define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */ |
121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ | 121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ |
122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ | 122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ |
123 | #define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ | 123 | #define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ |
124 | #define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ | 124 | #define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ |
125 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ | 125 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ |
126 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ | 126 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ |
127 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ | 127 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ |
128 | #define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ | 128 | #define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ |
129 | #define UCR4_IRSC (1<<5) /* IR special case */ | 129 | #define UCR4_IRSC (1<<5) /* IR special case */ |
130 | #define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ | 130 | #define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ |
131 | #define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ | 131 | #define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ |
132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ | 132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ |
133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ | 133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ |
134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ | 134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ |
135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ | 135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ |
136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ | 136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ |
137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) | 137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) |
138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ | 138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ |
139 | #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ | 139 | #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ |
140 | #define USR1_RTSS (1<<14) /* RTS pin status */ | 140 | #define USR1_RTSS (1<<14) /* RTS pin status */ |
141 | #define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ | 141 | #define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ |
142 | #define USR1_RTSD (1<<12) /* RTS delta */ | 142 | #define USR1_RTSD (1<<12) /* RTS delta */ |
143 | #define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ | 143 | #define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ |
144 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ | 144 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ |
145 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ | 145 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ |
146 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ | 146 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ |
147 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ | 147 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ |
148 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ | 148 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ |
149 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ | 149 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ |
150 | #define USR2_ADET (1<<15) /* Auto baud rate detect complete */ | 150 | #define USR2_ADET (1<<15) /* Auto baud rate detect complete */ |
151 | #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ | 151 | #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ |
152 | #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ | 152 | #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ |
153 | #define USR2_IDLE (1<<12) /* Idle condition */ | 153 | #define USR2_IDLE (1<<12) /* Idle condition */ |
154 | #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ | 154 | #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ |
155 | #define USR2_WAKE (1<<7) /* Wake */ | 155 | #define USR2_WAKE (1<<7) /* Wake */ |
156 | #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ | 156 | #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ |
157 | #define USR2_TXDC (1<<3) /* Transmitter complete */ | 157 | #define USR2_TXDC (1<<3) /* Transmitter complete */ |
158 | #define USR2_BRCD (1<<2) /* Break condition */ | 158 | #define USR2_BRCD (1<<2) /* Break condition */ |
159 | #define USR2_ORE (1<<1) /* Overrun error */ | 159 | #define USR2_ORE (1<<1) /* Overrun error */ |
160 | #define USR2_RDR (1<<0) /* Recv data ready */ | 160 | #define USR2_RDR (1<<0) /* Recv data ready */ |
161 | #define UTS_FRCPERR (1<<13) /* Force parity error */ | 161 | #define UTS_FRCPERR (1<<13) /* Force parity error */ |
162 | #define UTS_LOOP (1<<12) /* Loop tx and rx */ | 162 | #define UTS_LOOP (1<<12) /* Loop tx and rx */ |
163 | #define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ | 163 | #define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ |
164 | #define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ | 164 | #define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ |
165 | #define UTS_TXFULL (1<<4) /* TxFIFO full */ | 165 | #define UTS_TXFULL (1<<4) /* TxFIFO full */ |
166 | #define UTS_RXFULL (1<<3) /* RxFIFO full */ | 166 | #define UTS_RXFULL (1<<3) /* RxFIFO full */ |
167 | #define UTS_SOFTRST (1<<0) /* Software reset */ | 167 | #define UTS_SOFTRST (1<<0) /* Software reset */ |
168 | 168 | ||
169 | /* We've been assigned a range on the "Low-density serial ports" major */ | 169 | /* We've been assigned a range on the "Low-density serial ports" major */ |
170 | #define SERIAL_IMX_MAJOR 207 | 170 | #define SERIAL_IMX_MAJOR 207 |
171 | #define MINOR_START 16 | 171 | #define MINOR_START 16 |
172 | #define DEV_NAME "ttymxc" | 172 | #define DEV_NAME "ttymxc" |
173 | 173 | ||
174 | /* | 174 | /* |
@@ -199,7 +199,7 @@ struct imx_port { | |||
199 | struct uart_port port; | 199 | struct uart_port port; |
200 | struct timer_list timer; | 200 | struct timer_list timer; |
201 | unsigned int old_status; | 201 | unsigned int old_status; |
202 | int txirq,rxirq,rtsirq; | 202 | int txirq, rxirq, rtsirq; |
203 | unsigned int have_rtscts:1; | 203 | unsigned int have_rtscts:1; |
204 | unsigned int use_irda:1; | 204 | unsigned int use_irda:1; |
205 | unsigned int irda_inv_rx:1; | 205 | unsigned int irda_inv_rx:1; |
@@ -397,7 +397,7 @@ static void imx_stop_rx(struct uart_port *port) | |||
397 | unsigned long temp; | 397 | unsigned long temp; |
398 | 398 | ||
399 | temp = readl(sport->port.membase + UCR2); | 399 | temp = readl(sport->port.membase + UCR2); |
400 | writel(temp &~ UCR2_RXEN, sport->port.membase + UCR2); | 400 | writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2); |
401 | } | 401 | } |
402 | 402 | ||
403 | /* | 403 | /* |
@@ -490,9 +490,8 @@ static irqreturn_t imx_txint(int irq, void *dev_id) | |||
490 | struct circ_buf *xmit = &sport->port.state->xmit; | 490 | struct circ_buf *xmit = &sport->port.state->xmit; |
491 | unsigned long flags; | 491 | unsigned long flags; |
492 | 492 | ||
493 | spin_lock_irqsave(&sport->port.lock,flags); | 493 | spin_lock_irqsave(&sport->port.lock, flags); |
494 | if (sport->port.x_char) | 494 | if (sport->port.x_char) { |
495 | { | ||
496 | /* Send next char */ | 495 | /* Send next char */ |
497 | writel(sport->port.x_char, sport->port.membase + URTX0); | 496 | writel(sport->port.x_char, sport->port.membase + URTX0); |
498 | goto out; | 497 | goto out; |
@@ -509,18 +508,18 @@ static irqreturn_t imx_txint(int irq, void *dev_id) | |||
509 | uart_write_wakeup(&sport->port); | 508 | uart_write_wakeup(&sport->port); |
510 | 509 | ||
511 | out: | 510 | out: |
512 | spin_unlock_irqrestore(&sport->port.lock,flags); | 511 | spin_unlock_irqrestore(&sport->port.lock, flags); |
513 | return IRQ_HANDLED; | 512 | return IRQ_HANDLED; |
514 | } | 513 | } |
515 | 514 | ||
516 | static irqreturn_t imx_rxint(int irq, void *dev_id) | 515 | static irqreturn_t imx_rxint(int irq, void *dev_id) |
517 | { | 516 | { |
518 | struct imx_port *sport = dev_id; | 517 | struct imx_port *sport = dev_id; |
519 | unsigned int rx,flg,ignored = 0; | 518 | unsigned int rx, flg, ignored = 0; |
520 | struct tty_struct *tty = sport->port.state->port.tty; | 519 | struct tty_port *port = &sport->port.state->port; |
521 | unsigned long flags, temp; | 520 | unsigned long flags, temp; |
522 | 521 | ||
523 | spin_lock_irqsave(&sport->port.lock,flags); | 522 | spin_lock_irqsave(&sport->port.lock, flags); |
524 | 523 | ||
525 | while (readl(sport->port.membase + USR2) & USR2_RDR) { | 524 | while (readl(sport->port.membase + USR2) & USR2_RDR) { |
526 | flg = TTY_NORMAL; | 525 | flg = TTY_NORMAL; |
@@ -570,12 +569,12 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
570 | #endif | 569 | #endif |
571 | } | 570 | } |
572 | 571 | ||
573 | tty_insert_flip_char(tty, rx, flg); | 572 | tty_insert_flip_char(port, rx, flg); |
574 | } | 573 | } |
575 | 574 | ||
576 | out: | 575 | out: |
577 | spin_unlock_irqrestore(&sport->port.lock,flags); | 576 | spin_unlock_irqrestore(&sport->port.lock, flags); |
578 | tty_flip_buffer_push(tty); | 577 | tty_flip_buffer_push(port); |
579 | return IRQ_HANDLED; | 578 | return IRQ_HANDLED; |
580 | } | 579 | } |
581 | 580 | ||
@@ -654,7 +653,7 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
654 | 653 | ||
655 | temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK; | 654 | temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK; |
656 | 655 | ||
657 | if ( break_state != 0 ) | 656 | if (break_state != 0) |
658 | temp |= UCR1_SNDBRK; | 657 | temp |= UCR1_SNDBRK; |
659 | 658 | ||
660 | writel(temp, sport->port.membase + UCR1); | 659 | writel(temp, sport->port.membase + UCR1); |
@@ -696,8 +695,8 @@ static int imx_startup(struct uart_port *port) | |||
696 | temp |= UCR4_IRSC; | 695 | temp |= UCR4_IRSC; |
697 | 696 | ||
698 | /* set the trigger level for CTS */ | 697 | /* set the trigger level for CTS */ |
699 | temp &= ~(UCR4_CTSTL_MASK<< UCR4_CTSTL_SHF); | 698 | temp &= ~(UCR4_CTSTL_MASK << UCR4_CTSTL_SHF); |
700 | temp |= CTSTL<< UCR4_CTSTL_SHF; | 699 | temp |= CTSTL << UCR4_CTSTL_SHF; |
701 | 700 | ||
702 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); | 701 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); |
703 | 702 | ||
@@ -799,7 +798,7 @@ static int imx_startup(struct uart_port *port) | |||
799 | * Enable modem status interrupts | 798 | * Enable modem status interrupts |
800 | */ | 799 | */ |
801 | imx_enable_ms(&sport->port); | 800 | imx_enable_ms(&sport->port); |
802 | spin_unlock_irqrestore(&sport->port.lock,flags); | 801 | spin_unlock_irqrestore(&sport->port.lock, flags); |
803 | 802 | ||
804 | if (USE_IRDA(sport)) { | 803 | if (USE_IRDA(sport)) { |
805 | struct imxuart_platform_data *pdata; | 804 | struct imxuart_platform_data *pdata; |
@@ -909,7 +908,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
909 | ucr2 = UCR2_SRST | UCR2_IRTS; | 908 | ucr2 = UCR2_SRST | UCR2_IRTS; |
910 | 909 | ||
911 | if (termios->c_cflag & CRTSCTS) { | 910 | if (termios->c_cflag & CRTSCTS) { |
912 | if( sport->have_rtscts ) { | 911 | if (sport->have_rtscts) { |
913 | ucr2 &= ~UCR2_IRTS; | 912 | ucr2 &= ~UCR2_IRTS; |
914 | ucr2 |= UCR2_CTSC; | 913 | ucr2 |= UCR2_CTSC; |
915 | } else { | 914 | } else { |
@@ -969,12 +968,12 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
969 | writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), | 968 | writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), |
970 | sport->port.membase + UCR1); | 969 | sport->port.membase + UCR1); |
971 | 970 | ||
972 | while ( !(readl(sport->port.membase + USR2) & USR2_TXDC)) | 971 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)) |
973 | barrier(); | 972 | barrier(); |
974 | 973 | ||
975 | /* then, disable everything */ | 974 | /* then, disable everything */ |
976 | old_txrxen = readl(sport->port.membase + UCR2); | 975 | old_txrxen = readl(sport->port.membase + UCR2); |
977 | writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN), | 976 | writel(old_txrxen & ~(UCR2_TXEN | UCR2_RXEN), |
978 | sport->port.membase + UCR2); | 977 | sport->port.membase + UCR2); |
979 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); | 978 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); |
980 | 979 | ||
@@ -1212,9 +1211,15 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1212 | struct imx_port *sport = imx_ports[co->index]; | 1211 | struct imx_port *sport = imx_ports[co->index]; |
1213 | struct imx_port_ucrs old_ucr; | 1212 | struct imx_port_ucrs old_ucr; |
1214 | unsigned int ucr1; | 1213 | unsigned int ucr1; |
1215 | unsigned long flags; | 1214 | unsigned long flags = 0; |
1215 | int locked = 1; | ||
1216 | 1216 | ||
1217 | spin_lock_irqsave(&sport->port.lock, flags); | 1217 | if (sport->port.sysrq) |
1218 | locked = 0; | ||
1219 | else if (oops_in_progress) | ||
1220 | locked = spin_trylock_irqsave(&sport->port.lock, flags); | ||
1221 | else | ||
1222 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1218 | 1223 | ||
1219 | /* | 1224 | /* |
1220 | * First, save UCR1/2/3 and then disable interrupts | 1225 | * First, save UCR1/2/3 and then disable interrupts |
@@ -1241,7 +1246,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1241 | 1246 | ||
1242 | imx_port_ucrs_restore(&sport->port, &old_ucr); | 1247 | imx_port_ucrs_restore(&sport->port, &old_ucr); |
1243 | 1248 | ||
1244 | spin_unlock_irqrestore(&sport->port.lock, flags); | 1249 | if (locked) |
1250 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1245 | } | 1251 | } |
1246 | 1252 | ||
1247 | /* | 1253 | /* |
@@ -1255,7 +1261,7 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
1255 | 1261 | ||
1256 | if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) { | 1262 | if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) { |
1257 | /* ok, the port was enabled */ | 1263 | /* ok, the port was enabled */ |
1258 | unsigned int ucr2, ubir,ubmr, uartclk; | 1264 | unsigned int ucr2, ubir, ubmr, uartclk; |
1259 | unsigned int baud_raw; | 1265 | unsigned int baud_raw; |
1260 | unsigned int ucfr_rfdiv; | 1266 | unsigned int ucfr_rfdiv; |
1261 | 1267 | ||
@@ -1301,8 +1307,8 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
1301 | *baud = (baud_raw + 50) / 100 * 100; | 1307 | *baud = (baud_raw + 50) / 100 * 100; |
1302 | } | 1308 | } |
1303 | 1309 | ||
1304 | if(*baud != baud_raw) | 1310 | if (*baud != baud_raw) |
1305 | printk(KERN_INFO "Serial: Console IMX rounded baud rate from %d to %d\n", | 1311 | pr_info("Console IMX rounded baud rate from %d to %d\n", |
1306 | baud_raw, *baud); | 1312 | baud_raw, *baud); |
1307 | } | 1313 | } |
1308 | } | 1314 | } |
@@ -1324,7 +1330,7 @@ imx_console_setup(struct console *co, char *options) | |||
1324 | if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) | 1330 | if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) |
1325 | co->index = 0; | 1331 | co->index = 0; |
1326 | sport = imx_ports[co->index]; | 1332 | sport = imx_ports[co->index]; |
1327 | if(sport == NULL) | 1333 | if (sport == NULL) |
1328 | return -ENODEV; | 1334 | return -ENODEV; |
1329 | 1335 | ||
1330 | if (options) | 1336 | if (options) |
@@ -1462,7 +1468,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1462 | struct resource *res; | 1468 | struct resource *res; |
1463 | struct pinctrl *pinctrl; | 1469 | struct pinctrl *pinctrl; |
1464 | 1470 | ||
1465 | sport = kzalloc(sizeof(*sport), GFP_KERNEL); | 1471 | sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); |
1466 | if (!sport) | 1472 | if (!sport) |
1467 | return -ENOMEM; | 1473 | return -ENOMEM; |
1468 | 1474 | ||
@@ -1470,19 +1476,15 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1470 | if (ret > 0) | 1476 | if (ret > 0) |
1471 | serial_imx_probe_pdata(sport, pdev); | 1477 | serial_imx_probe_pdata(sport, pdev); |
1472 | else if (ret < 0) | 1478 | else if (ret < 0) |
1473 | goto free; | 1479 | return ret; |
1474 | 1480 | ||
1475 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1481 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1476 | if (!res) { | 1482 | if (!res) |
1477 | ret = -ENODEV; | 1483 | return -ENODEV; |
1478 | goto free; | ||
1479 | } | ||
1480 | 1484 | ||
1481 | base = ioremap(res->start, PAGE_SIZE); | 1485 | base = devm_ioremap(&pdev->dev, res->start, PAGE_SIZE); |
1482 | if (!base) { | 1486 | if (!base) |
1483 | ret = -ENOMEM; | 1487 | return -ENOMEM; |
1484 | goto free; | ||
1485 | } | ||
1486 | 1488 | ||
1487 | sport->port.dev = &pdev->dev; | 1489 | sport->port.dev = &pdev->dev; |
1488 | sport->port.mapbase = res->start; | 1490 | sport->port.mapbase = res->start; |
@@ -1504,21 +1506,21 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1504 | if (IS_ERR(pinctrl)) { | 1506 | if (IS_ERR(pinctrl)) { |
1505 | ret = PTR_ERR(pinctrl); | 1507 | ret = PTR_ERR(pinctrl); |
1506 | dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); | 1508 | dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); |
1507 | goto unmap; | 1509 | return ret; |
1508 | } | 1510 | } |
1509 | 1511 | ||
1510 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1512 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
1511 | if (IS_ERR(sport->clk_ipg)) { | 1513 | if (IS_ERR(sport->clk_ipg)) { |
1512 | ret = PTR_ERR(sport->clk_ipg); | 1514 | ret = PTR_ERR(sport->clk_ipg); |
1513 | dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret); | 1515 | dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret); |
1514 | goto unmap; | 1516 | return ret; |
1515 | } | 1517 | } |
1516 | 1518 | ||
1517 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); | 1519 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); |
1518 | if (IS_ERR(sport->clk_per)) { | 1520 | if (IS_ERR(sport->clk_per)) { |
1519 | ret = PTR_ERR(sport->clk_per); | 1521 | ret = PTR_ERR(sport->clk_per); |
1520 | dev_err(&pdev->dev, "failed to get per clk: %d\n", ret); | 1522 | dev_err(&pdev->dev, "failed to get per clk: %d\n", ret); |
1521 | goto unmap; | 1523 | return ret; |
1522 | } | 1524 | } |
1523 | 1525 | ||
1524 | clk_prepare_enable(sport->clk_per); | 1526 | clk_prepare_enable(sport->clk_per); |
@@ -1547,11 +1549,6 @@ deinit: | |||
1547 | clkput: | 1549 | clkput: |
1548 | clk_disable_unprepare(sport->clk_per); | 1550 | clk_disable_unprepare(sport->clk_per); |
1549 | clk_disable_unprepare(sport->clk_ipg); | 1551 | clk_disable_unprepare(sport->clk_ipg); |
1550 | unmap: | ||
1551 | iounmap(sport->port.membase); | ||
1552 | free: | ||
1553 | kfree(sport); | ||
1554 | |||
1555 | return ret; | 1552 | return ret; |
1556 | } | 1553 | } |
1557 | 1554 | ||
@@ -1572,9 +1569,6 @@ static int serial_imx_remove(struct platform_device *pdev) | |||
1572 | if (pdata && pdata->exit) | 1569 | if (pdata && pdata->exit) |
1573 | pdata->exit(pdev); | 1570 | pdata->exit(pdev); |
1574 | 1571 | ||
1575 | iounmap(sport->port.membase); | ||
1576 | kfree(sport); | ||
1577 | |||
1578 | return 0; | 1572 | return 0; |
1579 | } | 1573 | } |
1580 | 1574 | ||
@@ -1596,7 +1590,7 @@ static int __init imx_serial_init(void) | |||
1596 | { | 1590 | { |
1597 | int ret; | 1591 | int ret; |
1598 | 1592 | ||
1599 | printk(KERN_INFO "Serial: IMX driver\n"); | 1593 | pr_info("Serial: IMX driver\n"); |
1600 | 1594 | ||
1601 | ret = uart_register_driver(&imx_reg); | 1595 | ret = uart_register_driver(&imx_reg); |
1602 | if (ret) | 1596 | if (ret) |
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index d8f1d1d54471..6e4c715c5d26 100644 --- a/drivers/tty/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c | |||
@@ -1000,7 +1000,7 @@ ioc3_change_speed(struct uart_port *the_port, | |||
1000 | 1000 | ||
1001 | the_port->ignore_status_mask = N_ALL_INPUT; | 1001 | the_port->ignore_status_mask = N_ALL_INPUT; |
1002 | 1002 | ||
1003 | state->port.tty->low_latency = 1; | 1003 | state->port.low_latency = 1; |
1004 | 1004 | ||
1005 | if (iflag & IGNPAR) | 1005 | if (iflag & IGNPAR) |
1006 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR | 1006 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR |
@@ -1393,7 +1393,6 @@ static inline int do_read(struct uart_port *the_port, char *buf, int len) | |||
1393 | */ | 1393 | */ |
1394 | static int receive_chars(struct uart_port *the_port) | 1394 | static int receive_chars(struct uart_port *the_port) |
1395 | { | 1395 | { |
1396 | struct tty_struct *tty; | ||
1397 | unsigned char ch[MAX_CHARS]; | 1396 | unsigned char ch[MAX_CHARS]; |
1398 | int read_count = 0, read_room, flip = 0; | 1397 | int read_count = 0, read_room, flip = 0; |
1399 | struct uart_state *state = the_port->state; | 1398 | struct uart_state *state = the_port->state; |
@@ -1403,25 +1402,23 @@ static int receive_chars(struct uart_port *the_port) | |||
1403 | /* Make sure all the pointers are "good" ones */ | 1402 | /* Make sure all the pointers are "good" ones */ |
1404 | if (!state) | 1403 | if (!state) |
1405 | return 0; | 1404 | return 0; |
1406 | if (!state->port.tty) | ||
1407 | return 0; | ||
1408 | 1405 | ||
1409 | if (!(port->ip_flags & INPUT_ENABLE)) | 1406 | if (!(port->ip_flags & INPUT_ENABLE)) |
1410 | return 0; | 1407 | return 0; |
1411 | 1408 | ||
1412 | spin_lock_irqsave(&the_port->lock, pflags); | 1409 | spin_lock_irqsave(&the_port->lock, pflags); |
1413 | tty = state->port.tty; | ||
1414 | 1410 | ||
1415 | read_count = do_read(the_port, ch, MAX_CHARS); | 1411 | read_count = do_read(the_port, ch, MAX_CHARS); |
1416 | if (read_count > 0) { | 1412 | if (read_count > 0) { |
1417 | flip = 1; | 1413 | flip = 1; |
1418 | read_room = tty_insert_flip_string(tty, ch, read_count); | 1414 | read_room = tty_insert_flip_string(&state->port, ch, |
1415 | read_count); | ||
1419 | the_port->icount.rx += read_count; | 1416 | the_port->icount.rx += read_count; |
1420 | } | 1417 | } |
1421 | spin_unlock_irqrestore(&the_port->lock, pflags); | 1418 | spin_unlock_irqrestore(&the_port->lock, pflags); |
1422 | 1419 | ||
1423 | if (flip) | 1420 | if (flip) |
1424 | tty_flip_buffer_push(tty); | 1421 | tty_flip_buffer_push(&state->port); |
1425 | 1422 | ||
1426 | return read_count; | 1423 | return read_count; |
1427 | } | 1424 | } |
diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index 3e7da10cebba..e2520abcb1c4 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c | |||
@@ -1740,7 +1740,7 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1740 | 1740 | ||
1741 | the_port->ignore_status_mask = N_ALL_INPUT; | 1741 | the_port->ignore_status_mask = N_ALL_INPUT; |
1742 | 1742 | ||
1743 | state->port.tty->low_latency = 1; | 1743 | state->port.low_latency = 1; |
1744 | 1744 | ||
1745 | if (iflag & IGNPAR) | 1745 | if (iflag & IGNPAR) |
1746 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR | 1746 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR |
@@ -2340,7 +2340,6 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf, | |||
2340 | */ | 2340 | */ |
2341 | static void receive_chars(struct uart_port *the_port) | 2341 | static void receive_chars(struct uart_port *the_port) |
2342 | { | 2342 | { |
2343 | struct tty_struct *tty; | ||
2344 | unsigned char ch[IOC4_MAX_CHARS]; | 2343 | unsigned char ch[IOC4_MAX_CHARS]; |
2345 | int read_count, request_count = IOC4_MAX_CHARS; | 2344 | int read_count, request_count = IOC4_MAX_CHARS; |
2346 | struct uart_icount *icount; | 2345 | struct uart_icount *icount; |
@@ -2350,26 +2349,23 @@ static void receive_chars(struct uart_port *the_port) | |||
2350 | /* Make sure all the pointers are "good" ones */ | 2349 | /* Make sure all the pointers are "good" ones */ |
2351 | if (!state) | 2350 | if (!state) |
2352 | return; | 2351 | return; |
2353 | if (!state->port.tty) | ||
2354 | return; | ||
2355 | 2352 | ||
2356 | spin_lock_irqsave(&the_port->lock, pflags); | 2353 | spin_lock_irqsave(&the_port->lock, pflags); |
2357 | tty = state->port.tty; | ||
2358 | 2354 | ||
2359 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS); | 2355 | request_count = tty_buffer_request_room(&state->port, IOC4_MAX_CHARS); |
2360 | 2356 | ||
2361 | if (request_count > 0) { | 2357 | if (request_count > 0) { |
2362 | icount = &the_port->icount; | 2358 | icount = &the_port->icount; |
2363 | read_count = do_read(the_port, ch, request_count); | 2359 | read_count = do_read(the_port, ch, request_count); |
2364 | if (read_count > 0) { | 2360 | if (read_count > 0) { |
2365 | tty_insert_flip_string(tty, ch, read_count); | 2361 | tty_insert_flip_string(&state->port, ch, read_count); |
2366 | icount->rx += read_count; | 2362 | icount->rx += read_count; |
2367 | } | 2363 | } |
2368 | } | 2364 | } |
2369 | 2365 | ||
2370 | spin_unlock_irqrestore(&the_port->lock, pflags); | 2366 | spin_unlock_irqrestore(&the_port->lock, pflags); |
2371 | 2367 | ||
2372 | tty_flip_buffer_push(tty); | 2368 | tty_flip_buffer_push(&state->port); |
2373 | } | 2369 | } |
2374 | 2370 | ||
2375 | /** | 2371 | /** |
@@ -2883,6 +2879,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) | |||
2883 | /* error exits that give back resources */ | 2879 | /* error exits that give back resources */ |
2884 | out5: | 2880 | out5: |
2885 | ioc4_serial_remove_one(idd); | 2881 | ioc4_serial_remove_one(idd); |
2882 | return ret; | ||
2886 | out4: | 2883 | out4: |
2887 | kfree(soft); | 2884 | kfree(soft); |
2888 | out3: | 2885 | out3: |
diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 7b1cda59ebb5..cb3c81eb0996 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c | |||
@@ -248,17 +248,12 @@ static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up, | |||
248 | #define Rx_BRK 0x0100 /* BREAK event software flag. */ | 248 | #define Rx_BRK 0x0100 /* BREAK event software flag. */ |
249 | #define Rx_SYS 0x0200 /* SysRq event software flag. */ | 249 | #define Rx_SYS 0x0200 /* SysRq event software flag. */ |
250 | 250 | ||
251 | static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | 251 | static bool ip22zilog_receive_chars(struct uart_ip22zilog_port *up, |
252 | struct zilog_channel *channel) | 252 | struct zilog_channel *channel) |
253 | { | 253 | { |
254 | struct tty_struct *tty; | ||
255 | unsigned char ch, flag; | 254 | unsigned char ch, flag; |
256 | unsigned int r1; | 255 | unsigned int r1; |
257 | 256 | bool push = up->port.state != NULL; | |
258 | tty = NULL; | ||
259 | if (up->port.state != NULL && | ||
260 | up->port.state->port.tty != NULL) | ||
261 | tty = up->port.state->port.tty; | ||
262 | 257 | ||
263 | for (;;) { | 258 | for (;;) { |
264 | ch = readb(&channel->control); | 259 | ch = readb(&channel->control); |
@@ -312,10 +307,10 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up | |||
312 | if (uart_handle_sysrq_char(&up->port, ch)) | 307 | if (uart_handle_sysrq_char(&up->port, ch)) |
313 | continue; | 308 | continue; |
314 | 309 | ||
315 | if (tty) | 310 | if (push) |
316 | uart_insert_char(&up->port, r1, Rx_OVR, ch, flag); | 311 | uart_insert_char(&up->port, r1, Rx_OVR, ch, flag); |
317 | } | 312 | } |
318 | return tty; | 313 | return push; |
319 | } | 314 | } |
320 | 315 | ||
321 | static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, | 316 | static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, |
@@ -438,21 +433,20 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
438 | while (up) { | 433 | while (up) { |
439 | struct zilog_channel *channel | 434 | struct zilog_channel *channel |
440 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | 435 | = ZILOG_CHANNEL_FROM_PORT(&up->port); |
441 | struct tty_struct *tty; | ||
442 | unsigned char r3; | 436 | unsigned char r3; |
437 | bool push = false; | ||
443 | 438 | ||
444 | spin_lock(&up->port.lock); | 439 | spin_lock(&up->port.lock); |
445 | r3 = read_zsreg(channel, R3); | 440 | r3 = read_zsreg(channel, R3); |
446 | 441 | ||
447 | /* Channel A */ | 442 | /* Channel A */ |
448 | tty = NULL; | ||
449 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 443 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
450 | writeb(RES_H_IUS, &channel->control); | 444 | writeb(RES_H_IUS, &channel->control); |
451 | ZSDELAY(); | 445 | ZSDELAY(); |
452 | ZS_WSYNC(channel); | 446 | ZS_WSYNC(channel); |
453 | 447 | ||
454 | if (r3 & CHARxIP) | 448 | if (r3 & CHARxIP) |
455 | tty = ip22zilog_receive_chars(up, channel); | 449 | push = ip22zilog_receive_chars(up, channel); |
456 | if (r3 & CHAEXT) | 450 | if (r3 & CHAEXT) |
457 | ip22zilog_status_handle(up, channel); | 451 | ip22zilog_status_handle(up, channel); |
458 | if (r3 & CHATxIP) | 452 | if (r3 & CHATxIP) |
@@ -460,22 +454,22 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
460 | } | 454 | } |
461 | spin_unlock(&up->port.lock); | 455 | spin_unlock(&up->port.lock); |
462 | 456 | ||
463 | if (tty) | 457 | if (push) |
464 | tty_flip_buffer_push(tty); | 458 | tty_flip_buffer_push(&up->port.state->port); |
465 | 459 | ||
466 | /* Channel B */ | 460 | /* Channel B */ |
467 | up = up->next; | 461 | up = up->next; |
468 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | 462 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); |
463 | push = false; | ||
469 | 464 | ||
470 | spin_lock(&up->port.lock); | 465 | spin_lock(&up->port.lock); |
471 | tty = NULL; | ||
472 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 466 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
473 | writeb(RES_H_IUS, &channel->control); | 467 | writeb(RES_H_IUS, &channel->control); |
474 | ZSDELAY(); | 468 | ZSDELAY(); |
475 | ZS_WSYNC(channel); | 469 | ZS_WSYNC(channel); |
476 | 470 | ||
477 | if (r3 & CHBRxIP) | 471 | if (r3 & CHBRxIP) |
478 | tty = ip22zilog_receive_chars(up, channel); | 472 | push = ip22zilog_receive_chars(up, channel); |
479 | if (r3 & CHBEXT) | 473 | if (r3 & CHBEXT) |
480 | ip22zilog_status_handle(up, channel); | 474 | ip22zilog_status_handle(up, channel); |
481 | if (r3 & CHBTxIP) | 475 | if (r3 & CHBTxIP) |
@@ -483,8 +477,8 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
483 | } | 477 | } |
484 | spin_unlock(&up->port.lock); | 478 | spin_unlock(&up->port.lock); |
485 | 479 | ||
486 | if (tty) | 480 | if (push) |
487 | tty_flip_buffer_push(tty); | 481 | tty_flip_buffer_push(&up->port.state->port); |
488 | 482 | ||
489 | up = up->next; | 483 | up = up->next; |
490 | } | 484 | } |
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 4c00c5550b1a..00f250ae14c5 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c | |||
@@ -521,6 +521,7 @@ void jsm_input(struct jsm_channel *ch) | |||
521 | { | 521 | { |
522 | struct jsm_board *bd; | 522 | struct jsm_board *bd; |
523 | struct tty_struct *tp; | 523 | struct tty_struct *tp; |
524 | struct tty_port *port; | ||
524 | u32 rmask; | 525 | u32 rmask; |
525 | u16 head; | 526 | u16 head; |
526 | u16 tail; | 527 | u16 tail; |
@@ -536,7 +537,8 @@ void jsm_input(struct jsm_channel *ch) | |||
536 | if (!ch) | 537 | if (!ch) |
537 | return; | 538 | return; |
538 | 539 | ||
539 | tp = ch->uart_port.state->port.tty; | 540 | port = &ch->uart_port.state->port; |
541 | tp = port->tty; | ||
540 | 542 | ||
541 | bd = ch->ch_bd; | 543 | bd = ch->ch_bd; |
542 | if(!bd) | 544 | if(!bd) |
@@ -600,7 +602,7 @@ void jsm_input(struct jsm_channel *ch) | |||
600 | return; | 602 | return; |
601 | } | 603 | } |
602 | 604 | ||
603 | len = tty_buffer_request_room(tp, data_len); | 605 | len = tty_buffer_request_room(port, data_len); |
604 | n = len; | 606 | n = len; |
605 | 607 | ||
606 | /* | 608 | /* |
@@ -629,16 +631,16 @@ void jsm_input(struct jsm_channel *ch) | |||
629 | * format it likes. | 631 | * format it likes. |
630 | */ | 632 | */ |
631 | if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) | 633 | if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) |
632 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_BREAK); | 634 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_BREAK); |
633 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) | 635 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) |
634 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY); | 636 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_PARITY); |
635 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) | 637 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) |
636 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME); | 638 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_FRAME); |
637 | else | 639 | else |
638 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL); | 640 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_NORMAL); |
639 | } | 641 | } |
640 | } else { | 642 | } else { |
641 | tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; | 643 | tty_insert_flip_string(port, ch->ch_rqueue + tail, s); |
642 | } | 644 | } |
643 | tail += s; | 645 | tail += s; |
644 | n -= s; | 646 | n -= s; |
@@ -652,7 +654,7 @@ void jsm_input(struct jsm_channel *ch) | |||
652 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 654 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); |
653 | 655 | ||
654 | /* Tell the tty layer its okay to "eat" the data now */ | 656 | /* Tell the tty layer its okay to "eat" the data now */ |
655 | tty_flip_buffer_push(tp); | 657 | tty_flip_buffer_push(port); |
656 | 658 | ||
657 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); | 659 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); |
658 | } | 660 | } |
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 6ac2b797a764..5dafcf1c227b 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
24 | #include <linux/tty_driver.h> | 24 | #include <linux/tty_driver.h> |
25 | #include <linux/tty_flip.h> | 25 | #include <linux/tty_flip.h> |
26 | #include <linux/serial_core.h> | ||
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
27 | #include <linux/hrtimer.h> | 28 | #include <linux/hrtimer.h> |
28 | #include <linux/tick.h> | 29 | #include <linux/tick.h> |
@@ -202,7 +203,6 @@ bool kgdb_nmi_poll_knock(void) | |||
202 | static void kgdb_nmi_tty_receiver(unsigned long data) | 203 | static void kgdb_nmi_tty_receiver(unsigned long data) |
203 | { | 204 | { |
204 | struct kgdb_nmi_tty_priv *priv = (void *)data; | 205 | struct kgdb_nmi_tty_priv *priv = (void *)data; |
205 | struct tty_struct *tty; | ||
206 | char ch; | 206 | char ch; |
207 | 207 | ||
208 | tasklet_schedule(&priv->tlet); | 208 | tasklet_schedule(&priv->tlet); |
@@ -210,16 +210,9 @@ static void kgdb_nmi_tty_receiver(unsigned long data) | |||
210 | if (likely(!kgdb_nmi_tty_enabled || !kfifo_len(&priv->fifo))) | 210 | if (likely(!kgdb_nmi_tty_enabled || !kfifo_len(&priv->fifo))) |
211 | return; | 211 | return; |
212 | 212 | ||
213 | /* Port is there, but tty might be hung up, check. */ | ||
214 | tty = tty_port_tty_get(kgdb_nmi_port); | ||
215 | if (!tty) | ||
216 | return; | ||
217 | |||
218 | while (kfifo_out(&priv->fifo, &ch, 1)) | 213 | while (kfifo_out(&priv->fifo, &ch, 1)) |
219 | tty_insert_flip_char(priv->port.tty, ch, TTY_NORMAL); | 214 | tty_insert_flip_char(&priv->port, ch, TTY_NORMAL); |
220 | tty_flip_buffer_push(priv->port.tty); | 215 | tty_flip_buffer_push(&priv->port); |
221 | |||
222 | tty_kref_put(tty); | ||
223 | } | 216 | } |
224 | 217 | ||
225 | static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty) | 218 | static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty) |
diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 02da071fe1e7..15733da757c6 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c | |||
@@ -162,21 +162,16 @@ lqasc_enable_ms(struct uart_port *port) | |||
162 | static int | 162 | static int |
163 | lqasc_rx_chars(struct uart_port *port) | 163 | lqasc_rx_chars(struct uart_port *port) |
164 | { | 164 | { |
165 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 165 | struct tty_port *tport = &port->state->port; |
166 | unsigned int ch = 0, rsr = 0, fifocnt; | 166 | unsigned int ch = 0, rsr = 0, fifocnt; |
167 | 167 | ||
168 | if (!tty) { | 168 | fifocnt = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; |
169 | dev_dbg(port->dev, "%s:tty is busy now", __func__); | ||
170 | return -EBUSY; | ||
171 | } | ||
172 | fifocnt = | ||
173 | ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; | ||
174 | while (fifocnt--) { | 169 | while (fifocnt--) { |
175 | u8 flag = TTY_NORMAL; | 170 | u8 flag = TTY_NORMAL; |
176 | ch = ltq_r8(port->membase + LTQ_ASC_RBUF); | 171 | ch = ltq_r8(port->membase + LTQ_ASC_RBUF); |
177 | rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) | 172 | rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) |
178 | & ASCSTATE_ANY) | UART_DUMMY_UER_RX; | 173 | & ASCSTATE_ANY) | UART_DUMMY_UER_RX; |
179 | tty_flip_buffer_push(tty); | 174 | tty_flip_buffer_push(tport); |
180 | port->icount.rx++; | 175 | port->icount.rx++; |
181 | 176 | ||
182 | /* | 177 | /* |
@@ -208,7 +203,7 @@ lqasc_rx_chars(struct uart_port *port) | |||
208 | } | 203 | } |
209 | 204 | ||
210 | if ((rsr & port->ignore_status_mask) == 0) | 205 | if ((rsr & port->ignore_status_mask) == 0) |
211 | tty_insert_flip_char(tty, ch, flag); | 206 | tty_insert_flip_char(tport, ch, flag); |
212 | 207 | ||
213 | if (rsr & ASCSTATE_ROE) | 208 | if (rsr & ASCSTATE_ROE) |
214 | /* | 209 | /* |
@@ -216,11 +211,12 @@ lqasc_rx_chars(struct uart_port *port) | |||
216 | * immediately, and doesn't affect the current | 211 | * immediately, and doesn't affect the current |
217 | * character | 212 | * character |
218 | */ | 213 | */ |
219 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 214 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
220 | } | 215 | } |
216 | |||
221 | if (ch != 0) | 217 | if (ch != 0) |
222 | tty_flip_buffer_push(tty); | 218 | tty_flip_buffer_push(tport); |
223 | tty_kref_put(tty); | 219 | |
224 | return 0; | 220 | return 0; |
225 | } | 221 | } |
226 | 222 | ||
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index 0e86bff3fe2a..dffea6b2cd7d 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c | |||
@@ -257,17 +257,8 @@ static void __serial_uart_flush(struct uart_port *port) | |||
257 | 257 | ||
258 | static void __serial_lpc32xx_rx(struct uart_port *port) | 258 | static void __serial_lpc32xx_rx(struct uart_port *port) |
259 | { | 259 | { |
260 | struct tty_port *tport = &port->state->port; | ||
260 | unsigned int tmp, flag; | 261 | unsigned int tmp, flag; |
261 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
262 | |||
263 | if (!tty) { | ||
264 | /* Discard data: no tty available */ | ||
265 | while (!(readl(LPC32XX_HSUART_FIFO(port->membase)) & | ||
266 | LPC32XX_HSU_RX_EMPTY)) | ||
267 | ; | ||
268 | |||
269 | return; | ||
270 | } | ||
271 | 262 | ||
272 | /* Read data from FIFO and push into terminal */ | 263 | /* Read data from FIFO and push into terminal */ |
273 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | 264 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); |
@@ -281,15 +272,14 @@ static void __serial_lpc32xx_rx(struct uart_port *port) | |||
281 | LPC32XX_HSUART_IIR(port->membase)); | 272 | LPC32XX_HSUART_IIR(port->membase)); |
282 | port->icount.frame++; | 273 | port->icount.frame++; |
283 | flag = TTY_FRAME; | 274 | flag = TTY_FRAME; |
284 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 275 | tty_insert_flip_char(tport, 0, TTY_FRAME); |
285 | } | 276 | } |
286 | 277 | ||
287 | tty_insert_flip_char(tty, (tmp & 0xFF), flag); | 278 | tty_insert_flip_char(tport, (tmp & 0xFF), flag); |
288 | 279 | ||
289 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | 280 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); |
290 | } | 281 | } |
291 | tty_flip_buffer_push(tty); | 282 | tty_flip_buffer_push(tport); |
292 | tty_kref_put(tty); | ||
293 | } | 283 | } |
294 | 284 | ||
295 | static void __serial_lpc32xx_tx(struct uart_port *port) | 285 | static void __serial_lpc32xx_tx(struct uart_port *port) |
@@ -332,7 +322,7 @@ exit_tx: | |||
332 | static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | 322 | static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) |
333 | { | 323 | { |
334 | struct uart_port *port = dev_id; | 324 | struct uart_port *port = dev_id; |
335 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 325 | struct tty_port *tport = &port->state->port; |
336 | u32 status; | 326 | u32 status; |
337 | 327 | ||
338 | spin_lock(&port->lock); | 328 | spin_lock(&port->lock); |
@@ -356,17 +346,14 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | |||
356 | writel(LPC32XX_HSU_RX_OE_INT, | 346 | writel(LPC32XX_HSU_RX_OE_INT, |
357 | LPC32XX_HSUART_IIR(port->membase)); | 347 | LPC32XX_HSUART_IIR(port->membase)); |
358 | port->icount.overrun++; | 348 | port->icount.overrun++; |
359 | if (tty) { | 349 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
360 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 350 | tty_schedule_flip(tport); |
361 | tty_schedule_flip(tty); | ||
362 | } | ||
363 | } | 351 | } |
364 | 352 | ||
365 | /* Data received? */ | 353 | /* Data received? */ |
366 | if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { | 354 | if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { |
367 | __serial_lpc32xx_rx(port); | 355 | __serial_lpc32xx_rx(port); |
368 | if (tty) | 356 | tty_flip_buffer_push(tport); |
369 | tty_flip_buffer_push(tty); | ||
370 | } | 357 | } |
371 | 358 | ||
372 | /* Transmit data request? */ | 359 | /* Transmit data request? */ |
@@ -376,7 +363,6 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | |||
376 | } | 363 | } |
377 | 364 | ||
378 | spin_unlock(&port->lock); | 365 | spin_unlock(&port->lock); |
379 | tty_kref_put(tty); | ||
380 | 366 | ||
381 | return IRQ_HANDLED; | 367 | return IRQ_HANDLED; |
382 | } | 368 | } |
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index b13949ad3408..bb1afa0922e1 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
@@ -300,7 +300,7 @@ static void m32r_sio_enable_ms(struct uart_port *port) | |||
300 | 300 | ||
301 | static void receive_chars(struct uart_sio_port *up, int *status) | 301 | static void receive_chars(struct uart_sio_port *up, int *status) |
302 | { | 302 | { |
303 | struct tty_struct *tty = up->port.state->port.tty; | 303 | struct tty_port *port = &up->port.state->port; |
304 | unsigned char ch; | 304 | unsigned char ch; |
305 | unsigned char flag; | 305 | unsigned char flag; |
306 | int max_count = 256; | 306 | int max_count = 256; |
@@ -355,7 +355,7 @@ static void receive_chars(struct uart_sio_port *up, int *status) | |||
355 | if (uart_handle_sysrq_char(&up->port, ch)) | 355 | if (uart_handle_sysrq_char(&up->port, ch)) |
356 | goto ignore_char; | 356 | goto ignore_char; |
357 | if ((*status & up->port.ignore_status_mask) == 0) | 357 | if ((*status & up->port.ignore_status_mask) == 0) |
358 | tty_insert_flip_char(tty, ch, flag); | 358 | tty_insert_flip_char(port, ch, flag); |
359 | 359 | ||
360 | if (*status & UART_LSR_OE) { | 360 | if (*status & UART_LSR_OE) { |
361 | /* | 361 | /* |
@@ -363,12 +363,12 @@ static void receive_chars(struct uart_sio_port *up, int *status) | |||
363 | * immediately, and doesn't affect the current | 363 | * immediately, and doesn't affect the current |
364 | * character. | 364 | * character. |
365 | */ | 365 | */ |
366 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 366 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
367 | } | 367 | } |
368 | ignore_char: | 368 | ignore_char: |
369 | *status = serial_in(up, UART_LSR); | 369 | *status = serial_in(up, UART_LSR); |
370 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 370 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
371 | tty_flip_buffer_push(tty); | 371 | tty_flip_buffer_push(port); |
372 | } | 372 | } |
373 | 373 | ||
374 | static void transmit_chars(struct uart_sio_port *up) | 374 | static void transmit_chars(struct uart_sio_port *up) |
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index dd6277eb5a38..32517d4bceab 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
@@ -310,8 +310,8 @@ static void max3100_work(struct work_struct *w) | |||
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
313 | if (rxchars > 16 && s->port.state->port.tty != NULL) { | 313 | if (rxchars > 16) { |
314 | tty_flip_buffer_push(s->port.state->port.tty); | 314 | tty_flip_buffer_push(&s->port.state->port); |
315 | rxchars = 0; | 315 | rxchars = 0; |
316 | } | 316 | } |
317 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 317 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -323,8 +323,8 @@ static void max3100_work(struct work_struct *w) | |||
323 | (!uart_circ_empty(xmit) && | 323 | (!uart_circ_empty(xmit) && |
324 | !uart_tx_stopped(&s->port)))); | 324 | !uart_tx_stopped(&s->port)))); |
325 | 325 | ||
326 | if (rxchars > 0 && s->port.state->port.tty != NULL) | 326 | if (rxchars > 0) |
327 | tty_flip_buffer_push(s->port.state->port.tty); | 327 | tty_flip_buffer_push(&s->port.state->port); |
328 | } | 328 | } |
329 | 329 | ||
330 | static irqreturn_t max3100_irq(int irqno, void *dev_id) | 330 | static irqreturn_t max3100_irq(int irqno, void *dev_id) |
@@ -529,7 +529,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, | |||
529 | MAX3100_STATUS_OE; | 529 | MAX3100_STATUS_OE; |
530 | 530 | ||
531 | /* we are sending char from a workqueue so enable */ | 531 | /* we are sending char from a workqueue so enable */ |
532 | s->port.state->port.tty->low_latency = 1; | 532 | s->port.state->port.low_latency = 1; |
533 | 533 | ||
534 | if (s->poll_time > 0) | 534 | if (s->poll_time > 0) |
535 | del_timer_sync(&s->timer); | 535 | del_timer_sync(&s->timer); |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index a801f6872cad..0c2422cb04ea 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -460,10 +460,6 @@ static int max310x_set_ref_clk(struct max310x_port *s) | |||
460 | static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) | 460 | static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) |
461 | { | 461 | { |
462 | unsigned int sts = 0, ch = 0, flag; | 462 | unsigned int sts = 0, ch = 0, flag; |
463 | struct tty_struct *tty = tty_port_tty_get(&s->port.state->port); | ||
464 | |||
465 | if (!tty) | ||
466 | return; | ||
467 | 463 | ||
468 | if (unlikely(rxlen >= MAX310X_FIFO_SIZE)) { | 464 | if (unlikely(rxlen >= MAX310X_FIFO_SIZE)) { |
469 | dev_warn(s->port.dev, "Possible RX FIFO overrun %d\n", rxlen); | 465 | dev_warn(s->port.dev, "Possible RX FIFO overrun %d\n", rxlen); |
@@ -516,9 +512,7 @@ static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) | |||
516 | ch, flag); | 512 | ch, flag); |
517 | } | 513 | } |
518 | 514 | ||
519 | tty_flip_buffer_push(tty); | 515 | tty_flip_buffer_push(&s->port.state->port); |
520 | |||
521 | tty_kref_put(tty); | ||
522 | } | 516 | } |
523 | 517 | ||
524 | static void max310x_handle_tx(struct max310x_port *s) | 518 | static void max310x_handle_tx(struct max310x_port *s) |
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index fcd56ab6053f..e956377a38fe 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
24 | #include <linux/serial_core.h> | 24 | #include <linux/serial_core.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/uaccess.h> | ||
26 | #include <asm/coldfire.h> | 27 | #include <asm/coldfire.h> |
27 | #include <asm/mcfsim.h> | 28 | #include <asm/mcfsim.h> |
28 | #include <asm/mcfuart.h> | 29 | #include <asm/mcfuart.h> |
@@ -55,6 +56,7 @@ struct mcf_uart { | |||
55 | struct uart_port port; | 56 | struct uart_port port; |
56 | unsigned int sigs; /* Local copy of line sigs */ | 57 | unsigned int sigs; /* Local copy of line sigs */ |
57 | unsigned char imr; /* Local IMR mirror */ | 58 | unsigned char imr; /* Local IMR mirror */ |
59 | struct serial_rs485 rs485; /* RS485 settings */ | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | /****************************************************************************/ | 62 | /****************************************************************************/ |
@@ -101,6 +103,12 @@ static void mcf_start_tx(struct uart_port *port) | |||
101 | { | 103 | { |
102 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 104 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
103 | 105 | ||
106 | if (pp->rs485.flags & SER_RS485_ENABLED) { | ||
107 | /* Enable Transmitter */ | ||
108 | writeb(MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); | ||
109 | /* Manually assert RTS */ | ||
110 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); | ||
111 | } | ||
104 | pp->imr |= MCFUART_UIR_TXREADY; | 112 | pp->imr |= MCFUART_UIR_TXREADY; |
105 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 113 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
106 | } | 114 | } |
@@ -196,6 +204,7 @@ static void mcf_shutdown(struct uart_port *port) | |||
196 | static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | 204 | static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, |
197 | struct ktermios *old) | 205 | struct ktermios *old) |
198 | { | 206 | { |
207 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
199 | unsigned long flags; | 208 | unsigned long flags; |
200 | unsigned int baud, baudclk; | 209 | unsigned int baud, baudclk; |
201 | #if defined(CONFIG_M5272) | 210 | #if defined(CONFIG_M5272) |
@@ -248,6 +257,11 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | |||
248 | mr2 |= MCFUART_MR2_TXCTS; | 257 | mr2 |= MCFUART_MR2_TXCTS; |
249 | } | 258 | } |
250 | 259 | ||
260 | if (pp->rs485.flags & SER_RS485_ENABLED) { | ||
261 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
262 | mr2 |= MCFUART_MR2_TXRTS; | ||
263 | } | ||
264 | |||
251 | spin_lock_irqsave(&port->lock, flags); | 265 | spin_lock_irqsave(&port->lock, flags); |
252 | uart_update_timeout(port, termios->c_cflag, baud); | 266 | uart_update_timeout(port, termios->c_cflag, baud); |
253 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); | 267 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); |
@@ -310,7 +324,7 @@ static void mcf_rx_chars(struct mcf_uart *pp) | |||
310 | uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); | 324 | uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); |
311 | } | 325 | } |
312 | 326 | ||
313 | tty_flip_buffer_push(port->state->port.tty); | 327 | tty_flip_buffer_push(&port->state->port); |
314 | } | 328 | } |
315 | 329 | ||
316 | /****************************************************************************/ | 330 | /****************************************************************************/ |
@@ -342,6 +356,10 @@ static void mcf_tx_chars(struct mcf_uart *pp) | |||
342 | if (xmit->head == xmit->tail) { | 356 | if (xmit->head == xmit->tail) { |
343 | pp->imr &= ~MCFUART_UIR_TXREADY; | 357 | pp->imr &= ~MCFUART_UIR_TXREADY; |
344 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 358 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
359 | /* Disable TX to negate RTS automatically */ | ||
360 | if (pp->rs485.flags & SER_RS485_ENABLED) | ||
361 | writeb(MCFUART_UCR_TXDISABLE, | ||
362 | port->membase + MCFUART_UCR); | ||
345 | } | 363 | } |
346 | } | 364 | } |
347 | 365 | ||
@@ -418,6 +436,58 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
418 | 436 | ||
419 | /****************************************************************************/ | 437 | /****************************************************************************/ |
420 | 438 | ||
439 | /* Enable or disable the RS485 support */ | ||
440 | static void mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) | ||
441 | { | ||
442 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
443 | unsigned long flags; | ||
444 | unsigned char mr1, mr2; | ||
445 | |||
446 | spin_lock_irqsave(&port->lock, flags); | ||
447 | /* Get mode registers */ | ||
448 | mr1 = readb(port->membase + MCFUART_UMR); | ||
449 | mr2 = readb(port->membase + MCFUART_UMR); | ||
450 | if (rs485->flags & SER_RS485_ENABLED) { | ||
451 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
452 | /* Automatically negate RTS after TX completes */ | ||
453 | mr2 |= MCFUART_MR2_TXRTS; | ||
454 | } else { | ||
455 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
456 | mr2 &= ~MCFUART_MR2_TXRTS; | ||
457 | } | ||
458 | writeb(mr1, port->membase + MCFUART_UMR); | ||
459 | writeb(mr2, port->membase + MCFUART_UMR); | ||
460 | pp->rs485 = *rs485; | ||
461 | spin_unlock_irqrestore(&port->lock, flags); | ||
462 | } | ||
463 | |||
464 | static int mcf_ioctl(struct uart_port *port, unsigned int cmd, | ||
465 | unsigned long arg) | ||
466 | { | ||
467 | switch (cmd) { | ||
468 | case TIOCSRS485: { | ||
469 | struct serial_rs485 rs485; | ||
470 | if (copy_from_user(&rs485, (struct serial_rs485 *)arg, | ||
471 | sizeof(struct serial_rs485))) | ||
472 | return -EFAULT; | ||
473 | mcf_config_rs485(port, &rs485); | ||
474 | break; | ||
475 | } | ||
476 | case TIOCGRS485: { | ||
477 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
478 | if (copy_to_user((struct serial_rs485 *)arg, &pp->rs485, | ||
479 | sizeof(struct serial_rs485))) | ||
480 | return -EFAULT; | ||
481 | break; | ||
482 | } | ||
483 | default: | ||
484 | return -ENOIOCTLCMD; | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | /****************************************************************************/ | ||
490 | |||
421 | /* | 491 | /* |
422 | * Define the basic serial functions we support. | 492 | * Define the basic serial functions we support. |
423 | */ | 493 | */ |
@@ -438,6 +508,7 @@ static const struct uart_ops mcf_uart_ops = { | |||
438 | .release_port = mcf_release_port, | 508 | .release_port = mcf_release_port, |
439 | .config_port = mcf_config_port, | 509 | .config_port = mcf_config_port, |
440 | .verify_port = mcf_verify_port, | 510 | .verify_port = mcf_verify_port, |
511 | .ioctl = mcf_ioctl, | ||
441 | }; | 512 | }; |
442 | 513 | ||
443 | static struct mcf_uart mcf_ports[4]; | 514 | static struct mcf_uart mcf_ports[4]; |
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 2c01344dc332..5f4765a7a5c5 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c | |||
@@ -387,12 +387,9 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
387 | struct hsu_dma_buffer *dbuf = &up->rxbuf; | 387 | struct hsu_dma_buffer *dbuf = &up->rxbuf; |
388 | struct hsu_dma_chan *chan = up->rxc; | 388 | struct hsu_dma_chan *chan = up->rxc; |
389 | struct uart_port *port = &up->port; | 389 | struct uart_port *port = &up->port; |
390 | struct tty_struct *tty = port->state->port.tty; | 390 | struct tty_port *tport = &port->state->port; |
391 | int count; | 391 | int count; |
392 | 392 | ||
393 | if (!tty) | ||
394 | return; | ||
395 | |||
396 | /* | 393 | /* |
397 | * First need to know how many is already transferred, | 394 | * First need to know how many is already transferred, |
398 | * then check if its a timeout DMA irq, and return | 395 | * then check if its a timeout DMA irq, and return |
@@ -423,7 +420,7 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
423 | * explicitly set tail to 0. So head will | 420 | * explicitly set tail to 0. So head will |
424 | * always be greater than tail. | 421 | * always be greater than tail. |
425 | */ | 422 | */ |
426 | tty_insert_flip_string(tty, dbuf->buf, count); | 423 | tty_insert_flip_string(tport, dbuf->buf, count); |
427 | port->icount.rx += count; | 424 | port->icount.rx += count; |
428 | 425 | ||
429 | dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, | 426 | dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, |
@@ -437,7 +434,7 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
437 | | (0x1 << 16) | 434 | | (0x1 << 16) |
438 | | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ | 435 | | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ |
439 | ); | 436 | ); |
440 | tty_flip_buffer_push(tty); | 437 | tty_flip_buffer_push(tport); |
441 | 438 | ||
442 | chan_writel(chan, HSU_CH_CR, 0x3); | 439 | chan_writel(chan, HSU_CH_CR, 0x3); |
443 | 440 | ||
@@ -460,13 +457,9 @@ static void serial_hsu_stop_rx(struct uart_port *port) | |||
460 | 457 | ||
461 | static inline void receive_chars(struct uart_hsu_port *up, int *status) | 458 | static inline void receive_chars(struct uart_hsu_port *up, int *status) |
462 | { | 459 | { |
463 | struct tty_struct *tty = up->port.state->port.tty; | ||
464 | unsigned int ch, flag; | 460 | unsigned int ch, flag; |
465 | unsigned int max_count = 256; | 461 | unsigned int max_count = 256; |
466 | 462 | ||
467 | if (!tty) | ||
468 | return; | ||
469 | |||
470 | do { | 463 | do { |
471 | ch = serial_in(up, UART_RX); | 464 | ch = serial_in(up, UART_RX); |
472 | flag = TTY_NORMAL; | 465 | flag = TTY_NORMAL; |
@@ -522,7 +515,7 @@ static inline void receive_chars(struct uart_hsu_port *up, int *status) | |||
522 | ignore_char: | 515 | ignore_char: |
523 | *status = serial_in(up, UART_LSR); | 516 | *status = serial_in(up, UART_LSR); |
524 | } while ((*status & UART_LSR_DR) && max_count--); | 517 | } while ((*status & UART_LSR_DR) && max_count--); |
525 | tty_flip_buffer_push(tty); | 518 | tty_flip_buffer_push(&up->port.state->port); |
526 | } | 519 | } |
527 | 520 | ||
528 | static void transmit_chars(struct uart_hsu_port *up) | 521 | static void transmit_chars(struct uart_hsu_port *up) |
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 7c23c4f4c58d..c0e1fad51be7 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -941,7 +941,7 @@ static struct uart_ops mpc52xx_uart_ops = { | |||
941 | static inline int | 941 | static inline int |
942 | mpc52xx_uart_int_rx_chars(struct uart_port *port) | 942 | mpc52xx_uart_int_rx_chars(struct uart_port *port) |
943 | { | 943 | { |
944 | struct tty_struct *tty = port->state->port.tty; | 944 | struct tty_port *tport = &port->state->port; |
945 | unsigned char ch, flag; | 945 | unsigned char ch, flag; |
946 | unsigned short status; | 946 | unsigned short status; |
947 | 947 | ||
@@ -986,20 +986,20 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
986 | out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); | 986 | out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); |
987 | 987 | ||
988 | } | 988 | } |
989 | tty_insert_flip_char(tty, ch, flag); | 989 | tty_insert_flip_char(tport, ch, flag); |
990 | if (status & MPC52xx_PSC_SR_OE) { | 990 | if (status & MPC52xx_PSC_SR_OE) { |
991 | /* | 991 | /* |
992 | * Overrun is special, since it's | 992 | * Overrun is special, since it's |
993 | * reported immediately, and doesn't | 993 | * reported immediately, and doesn't |
994 | * affect the current character | 994 | * affect the current character |
995 | */ | 995 | */ |
996 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 996 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
997 | port->icount.overrun++; | 997 | port->icount.overrun++; |
998 | } | 998 | } |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | spin_unlock(&port->lock); | 1001 | spin_unlock(&port->lock); |
1002 | tty_flip_buffer_push(tty); | 1002 | tty_flip_buffer_push(tport); |
1003 | spin_lock(&port->lock); | 1003 | spin_lock(&port->lock); |
1004 | 1004 | ||
1005 | return psc_ops->raw_rx_rdy(port); | 1005 | return psc_ops->raw_rx_rdy(port); |
diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index 6a9c6605666a..bc24f4931670 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c | |||
@@ -937,7 +937,7 @@ static int serial_polled; | |||
937 | static int mpsc_rx_intr(struct mpsc_port_info *pi) | 937 | static int mpsc_rx_intr(struct mpsc_port_info *pi) |
938 | { | 938 | { |
939 | struct mpsc_rx_desc *rxre; | 939 | struct mpsc_rx_desc *rxre; |
940 | struct tty_struct *tty = pi->port.state->port.tty; | 940 | struct tty_port *port = &pi->port.state->port; |
941 | u32 cmdstat, bytes_in, i; | 941 | u32 cmdstat, bytes_in, i; |
942 | int rc = 0; | 942 | int rc = 0; |
943 | u8 *bp; | 943 | u8 *bp; |
@@ -968,10 +968,9 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) | |||
968 | } | 968 | } |
969 | #endif | 969 | #endif |
970 | /* Following use of tty struct directly is deprecated */ | 970 | /* Following use of tty struct directly is deprecated */ |
971 | if (unlikely(tty_buffer_request_room(tty, bytes_in) | 971 | if (tty_buffer_request_room(port, bytes_in) < bytes_in) { |
972 | < bytes_in)) { | 972 | if (port->low_latency) |
973 | if (tty->low_latency) | 973 | tty_flip_buffer_push(port); |
974 | tty_flip_buffer_push(tty); | ||
975 | /* | 974 | /* |
976 | * If this failed then we will throw away the bytes | 975 | * If this failed then we will throw away the bytes |
977 | * but must do so to clear interrupts. | 976 | * but must do so to clear interrupts. |
@@ -1040,10 +1039,10 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) | |||
1040 | | SDMA_DESC_CMDSTAT_FR | 1039 | | SDMA_DESC_CMDSTAT_FR |
1041 | | SDMA_DESC_CMDSTAT_OR))) | 1040 | | SDMA_DESC_CMDSTAT_OR))) |
1042 | && !(cmdstat & pi->port.ignore_status_mask)) { | 1041 | && !(cmdstat & pi->port.ignore_status_mask)) { |
1043 | tty_insert_flip_char(tty, *bp, flag); | 1042 | tty_insert_flip_char(port, *bp, flag); |
1044 | } else { | 1043 | } else { |
1045 | for (i=0; i<bytes_in; i++) | 1044 | for (i=0; i<bytes_in; i++) |
1046 | tty_insert_flip_char(tty, *bp++, TTY_NORMAL); | 1045 | tty_insert_flip_char(port, *bp++, TTY_NORMAL); |
1047 | 1046 | ||
1048 | pi->port.icount.rx += bytes_in; | 1047 | pi->port.icount.rx += bytes_in; |
1049 | } | 1048 | } |
@@ -1081,7 +1080,7 @@ next_frame: | |||
1081 | if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) | 1080 | if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) |
1082 | mpsc_start_rx(pi); | 1081 | mpsc_start_rx(pi); |
1083 | 1082 | ||
1084 | tty_flip_buffer_push(tty); | 1083 | tty_flip_buffer_push(port); |
1085 | return rc; | 1084 | return rc; |
1086 | } | 1085 | } |
1087 | 1086 | ||
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 58734d7e746d..f641c232beca 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c | |||
@@ -339,7 +339,7 @@ static int | |||
339 | receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | 339 | receive_chars(struct uart_max3110 *max, unsigned short *str, int len) |
340 | { | 340 | { |
341 | struct uart_port *port = &max->port; | 341 | struct uart_port *port = &max->port; |
342 | struct tty_struct *tty; | 342 | struct tty_port *tport; |
343 | char buf[M3110_RX_FIFO_DEPTH]; | 343 | char buf[M3110_RX_FIFO_DEPTH]; |
344 | int r, w, usable; | 344 | int r, w, usable; |
345 | 345 | ||
@@ -347,9 +347,7 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | |||
347 | if (!port->state) | 347 | if (!port->state) |
348 | return 0; | 348 | return 0; |
349 | 349 | ||
350 | tty = tty_port_tty_get(&port->state->port); | 350 | tport = &port->state->port; |
351 | if (!tty) | ||
352 | return 0; | ||
353 | 351 | ||
354 | for (r = 0, w = 0; r < len; r++) { | 352 | for (r = 0, w = 0; r < len; r++) { |
355 | if (str[r] & MAX3110_BREAK && | 353 | if (str[r] & MAX3110_BREAK && |
@@ -364,20 +362,17 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | |||
364 | } | 362 | } |
365 | } | 363 | } |
366 | 364 | ||
367 | if (!w) { | 365 | if (!w) |
368 | tty_kref_put(tty); | ||
369 | return 0; | 366 | return 0; |
370 | } | ||
371 | 367 | ||
372 | for (r = 0; w; r += usable, w -= usable) { | 368 | for (r = 0; w; r += usable, w -= usable) { |
373 | usable = tty_buffer_request_room(tty, w); | 369 | usable = tty_buffer_request_room(tport, w); |
374 | if (usable) { | 370 | if (usable) { |
375 | tty_insert_flip_string(tty, buf + r, usable); | 371 | tty_insert_flip_string(tport, buf + r, usable); |
376 | port->icount.rx += usable; | 372 | port->icount.rx += usable; |
377 | } | 373 | } |
378 | } | 374 | } |
379 | tty_flip_buffer_push(tty); | 375 | tty_flip_buffer_push(tport); |
380 | tty_kref_put(tty); | ||
381 | 376 | ||
382 | return r; | 377 | return r; |
383 | } | 378 | } |
@@ -493,7 +488,7 @@ static int serial_m3110_startup(struct uart_port *port) | |||
493 | | WC_BAUD_DR2; | 488 | | WC_BAUD_DR2; |
494 | 489 | ||
495 | /* as we use thread to handle tx/rx, need set low latency */ | 490 | /* as we use thread to handle tx/rx, need set low latency */ |
496 | port->state->port.tty->low_latency = 1; | 491 | port->state->port.low_latency = 1; |
497 | 492 | ||
498 | if (max->irq) { | 493 | if (max->irq) { |
499 | max->read_thread = NULL; | 494 | max->read_thread = NULL; |
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 95fd39be2934..b11e99797fd8 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -91,14 +91,14 @@ static void msm_enable_ms(struct uart_port *port) | |||
91 | 91 | ||
92 | static void handle_rx_dm(struct uart_port *port, unsigned int misr) | 92 | static void handle_rx_dm(struct uart_port *port, unsigned int misr) |
93 | { | 93 | { |
94 | struct tty_struct *tty = port->state->port.tty; | 94 | struct tty_port *tport = &port->state->port; |
95 | unsigned int sr; | 95 | unsigned int sr; |
96 | int count = 0; | 96 | int count = 0; |
97 | struct msm_port *msm_port = UART_TO_MSM(port); | 97 | struct msm_port *msm_port = UART_TO_MSM(port); |
98 | 98 | ||
99 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { | 99 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { |
100 | port->icount.overrun++; | 100 | port->icount.overrun++; |
101 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 101 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
102 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); | 102 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); |
103 | } | 103 | } |
104 | 104 | ||
@@ -132,12 +132,12 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) | |||
132 | port->icount.frame++; | 132 | port->icount.frame++; |
133 | 133 | ||
134 | /* TODO: handle sysrq */ | 134 | /* TODO: handle sysrq */ |
135 | tty_insert_flip_string(tty, (char *) &c, | 135 | tty_insert_flip_string(tport, (char *)&c, |
136 | (count > 4) ? 4 : count); | 136 | (count > 4) ? 4 : count); |
137 | count -= 4; | 137 | count -= 4; |
138 | } | 138 | } |
139 | 139 | ||
140 | tty_flip_buffer_push(tty); | 140 | tty_flip_buffer_push(tport); |
141 | if (misr & (UART_IMR_RXSTALE)) | 141 | if (misr & (UART_IMR_RXSTALE)) |
142 | msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); | 142 | msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); |
143 | msm_write(port, 0xFFFFFF, UARTDM_DMRX); | 143 | msm_write(port, 0xFFFFFF, UARTDM_DMRX); |
@@ -146,7 +146,7 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) | |||
146 | 146 | ||
147 | static void handle_rx(struct uart_port *port) | 147 | static void handle_rx(struct uart_port *port) |
148 | { | 148 | { |
149 | struct tty_struct *tty = port->state->port.tty; | 149 | struct tty_port *tport = &port->state->port; |
150 | unsigned int sr; | 150 | unsigned int sr; |
151 | 151 | ||
152 | /* | 152 | /* |
@@ -155,7 +155,7 @@ static void handle_rx(struct uart_port *port) | |||
155 | */ | 155 | */ |
156 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { | 156 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { |
157 | port->icount.overrun++; | 157 | port->icount.overrun++; |
158 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 158 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
159 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); | 159 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); |
160 | } | 160 | } |
161 | 161 | ||
@@ -186,10 +186,10 @@ static void handle_rx(struct uart_port *port) | |||
186 | } | 186 | } |
187 | 187 | ||
188 | if (!uart_handle_sysrq_char(port, c)) | 188 | if (!uart_handle_sysrq_char(port, c)) |
189 | tty_insert_flip_char(tty, c, flag); | 189 | tty_insert_flip_char(tport, c, flag); |
190 | } | 190 | } |
191 | 191 | ||
192 | tty_flip_buffer_push(tty); | 192 | tty_flip_buffer_push(tport); |
193 | } | 193 | } |
194 | 194 | ||
195 | static void reset_dm_count(struct uart_port *port) | 195 | static void reset_dm_count(struct uart_port *port) |
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 1fa92284ade0..4a942c78347e 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c | |||
@@ -908,6 +908,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
908 | unsigned long flags; | 908 | unsigned long flags; |
909 | unsigned int flush; | 909 | unsigned int flush; |
910 | struct tty_struct *tty; | 910 | struct tty_struct *tty; |
911 | struct tty_port *port; | ||
911 | struct uart_port *uport; | 912 | struct uart_port *uport; |
912 | struct msm_hs_port *msm_uport; | 913 | struct msm_hs_port *msm_uport; |
913 | 914 | ||
@@ -917,7 +918,8 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
917 | spin_lock_irqsave(&uport->lock, flags); | 918 | spin_lock_irqsave(&uport->lock, flags); |
918 | clk_enable(msm_uport->clk); | 919 | clk_enable(msm_uport->clk); |
919 | 920 | ||
920 | tty = uport->state->port.tty; | 921 | port = &uport->state->port; |
922 | tty = port->tty; | ||
921 | 923 | ||
922 | msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); | 924 | msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); |
923 | 925 | ||
@@ -926,7 +928,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
926 | /* overflow is not connect to data in a FIFO */ | 928 | /* overflow is not connect to data in a FIFO */ |
927 | if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) && | 929 | if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) && |
928 | (uport->read_status_mask & CREAD))) { | 930 | (uport->read_status_mask & CREAD))) { |
929 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 931 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
930 | uport->icount.buf_overrun++; | 932 | uport->icount.buf_overrun++; |
931 | error_f = 1; | 933 | error_f = 1; |
932 | } | 934 | } |
@@ -939,7 +941,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
939 | uport->icount.parity++; | 941 | uport->icount.parity++; |
940 | error_f = 1; | 942 | error_f = 1; |
941 | if (uport->ignore_status_mask & IGNPAR) | 943 | if (uport->ignore_status_mask & IGNPAR) |
942 | tty_insert_flip_char(tty, 0, TTY_PARITY); | 944 | tty_insert_flip_char(port, 0, TTY_PARITY); |
943 | } | 945 | } |
944 | 946 | ||
945 | if (error_f) | 947 | if (error_f) |
@@ -959,7 +961,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
959 | rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR); | 961 | rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR); |
960 | 962 | ||
961 | if (0 != (uport->read_status_mask & CREAD)) { | 963 | if (0 != (uport->read_status_mask & CREAD)) { |
962 | retval = tty_insert_flip_string(tty, msm_uport->rx.buffer, | 964 | retval = tty_insert_flip_string(port, msm_uport->rx.buffer, |
963 | rx_count); | 965 | rx_count); |
964 | BUG_ON(retval != rx_count); | 966 | BUG_ON(retval != rx_count); |
965 | } | 967 | } |
@@ -979,9 +981,8 @@ static void msm_hs_tty_flip_buffer_work(struct work_struct *work) | |||
979 | { | 981 | { |
980 | struct msm_hs_port *msm_uport = | 982 | struct msm_hs_port *msm_uport = |
981 | container_of(work, struct msm_hs_port, rx.tty_work); | 983 | container_of(work, struct msm_hs_port, rx.tty_work); |
982 | struct tty_struct *tty = msm_uport->uport.state->port.tty; | ||
983 | 984 | ||
984 | tty_flip_buffer_push(tty); | 985 | tty_flip_buffer_push(&msm_uport->uport.state->port); |
985 | } | 986 | } |
986 | 987 | ||
987 | /* | 988 | /* |
@@ -1344,7 +1345,6 @@ static irqreturn_t msm_hs_rx_wakeup_isr(int irq, void *dev) | |||
1344 | unsigned long flags; | 1345 | unsigned long flags; |
1345 | struct msm_hs_port *msm_uport = dev; | 1346 | struct msm_hs_port *msm_uport = dev; |
1346 | struct uart_port *uport = &msm_uport->uport; | 1347 | struct uart_port *uport = &msm_uport->uport; |
1347 | struct tty_struct *tty = NULL; | ||
1348 | 1348 | ||
1349 | spin_lock_irqsave(&uport->lock, flags); | 1349 | spin_lock_irqsave(&uport->lock, flags); |
1350 | if (msm_uport->clk_state == MSM_HS_CLK_OFF) { | 1350 | if (msm_uport->clk_state == MSM_HS_CLK_OFF) { |
@@ -1361,8 +1361,7 @@ static irqreturn_t msm_hs_rx_wakeup_isr(int irq, void *dev) | |||
1361 | * optionally inject char into tty rx */ | 1361 | * optionally inject char into tty rx */ |
1362 | msm_hs_request_clock_on_locked(uport); | 1362 | msm_hs_request_clock_on_locked(uport); |
1363 | if (msm_uport->rx_wakeup.inject_rx) { | 1363 | if (msm_uport->rx_wakeup.inject_rx) { |
1364 | tty = uport->state->port.tty; | 1364 | tty_insert_flip_char(&uport->state->port, |
1365 | tty_insert_flip_char(tty, | ||
1366 | msm_uport->rx_wakeup.rx_to_inject, | 1365 | msm_uport->rx_wakeup.rx_to_inject, |
1367 | TTY_NORMAL); | 1366 | TTY_NORMAL); |
1368 | queue_work(msm_hs_workqueue, &msm_uport->rx.tty_work); | 1367 | queue_work(msm_hs_workqueue, &msm_uport->rx.tty_work); |
@@ -1400,7 +1399,7 @@ static int msm_hs_startup(struct uart_port *uport) | |||
1400 | 1399 | ||
1401 | /* do not let tty layer execute RX in global workqueue, use a | 1400 | /* do not let tty layer execute RX in global workqueue, use a |
1402 | * dedicated workqueue managed by this driver */ | 1401 | * dedicated workqueue managed by this driver */ |
1403 | uport->state->port.tty->low_latency = 1; | 1402 | uport->state->port.low_latency = 1; |
1404 | 1403 | ||
1405 | /* turn on uart clk */ | 1404 | /* turn on uart clk */ |
1406 | ret = msm_hs_init_clk_locked(uport); | 1405 | ret = msm_hs_init_clk_locked(uport); |
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index 925d1fa153db..e722ff163d91 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c | |||
@@ -70,7 +70,7 @@ static void smd_tty_notify(void *priv, unsigned event) | |||
70 | if (avail == 0) | 70 | if (avail == 0) |
71 | break; | 71 | break; |
72 | 72 | ||
73 | avail = tty_prepare_flip_string(tty, &ptr, avail); | 73 | avail = tty_prepare_flip_string(&info->port, &ptr, avail); |
74 | 74 | ||
75 | if (smd_read(info->ch, ptr, avail) != avail) { | 75 | if (smd_read(info->ch, ptr, avail) != avail) { |
76 | /* shouldn't be possible since we're in interrupt | 76 | /* shouldn't be possible since we're in interrupt |
@@ -80,7 +80,7 @@ static void smd_tty_notify(void *priv, unsigned event) | |||
80 | pr_err("OOPS - smd_tty_buffer mismatch?!"); | 80 | pr_err("OOPS - smd_tty_buffer mismatch?!"); |
81 | } | 81 | } |
82 | 82 | ||
83 | tty_flip_buffer_push(tty); | 83 | tty_flip_buffer_push(&info->port); |
84 | } | 84 | } |
85 | 85 | ||
86 | /* XXX only when writable and necessary */ | 86 | /* XXX only when writable and necessary */ |
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index e2775b6df5a5..7fd6aaaacd8e 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c | |||
@@ -242,8 +242,8 @@ static void mux_write(struct uart_port *port) | |||
242 | */ | 242 | */ |
243 | static void mux_read(struct uart_port *port) | 243 | static void mux_read(struct uart_port *port) |
244 | { | 244 | { |
245 | struct tty_port *tport = &port->state->port; | ||
245 | int data; | 246 | int data; |
246 | struct tty_struct *tty = port->state->port.tty; | ||
247 | __u32 start_count = port->icount.rx; | 247 | __u32 start_count = port->icount.rx; |
248 | 248 | ||
249 | while(1) { | 249 | while(1) { |
@@ -266,12 +266,11 @@ static void mux_read(struct uart_port *port) | |||
266 | if (uart_handle_sysrq_char(port, data & 0xffu)) | 266 | if (uart_handle_sysrq_char(port, data & 0xffu)) |
267 | continue; | 267 | continue; |
268 | 268 | ||
269 | tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); | 269 | tty_insert_flip_char(tport, data & 0xFF, TTY_NORMAL); |
270 | } | 270 | } |
271 | 271 | ||
272 | if (start_count != port->icount.rx) { | 272 | if (start_count != port->icount.rx) |
273 | tty_flip_buffer_push(tty); | 273 | tty_flip_buffer_push(tport); |
274 | } | ||
275 | } | 274 | } |
276 | 275 | ||
277 | /** | 276 | /** |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index e55615eb34ad..d549fe1fa42a 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -364,7 +364,6 @@ out: | |||
364 | 364 | ||
365 | static void mxs_auart_rx_chars(struct mxs_auart_port *s) | 365 | static void mxs_auart_rx_chars(struct mxs_auart_port *s) |
366 | { | 366 | { |
367 | struct tty_struct *tty = s->port.state->port.tty; | ||
368 | u32 stat = 0; | 367 | u32 stat = 0; |
369 | 368 | ||
370 | for (;;) { | 369 | for (;;) { |
@@ -375,7 +374,7 @@ static void mxs_auart_rx_chars(struct mxs_auart_port *s) | |||
375 | } | 374 | } |
376 | 375 | ||
377 | writel(stat, s->port.membase + AUART_STAT); | 376 | writel(stat, s->port.membase + AUART_STAT); |
378 | tty_flip_buffer_push(tty); | 377 | tty_flip_buffer_push(&s->port.state->port); |
379 | } | 378 | } |
380 | 379 | ||
381 | static int mxs_auart_request_port(struct uart_port *u) | 380 | static int mxs_auart_request_port(struct uart_port *u) |
@@ -459,7 +458,7 @@ static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); | |||
459 | static void dma_rx_callback(void *arg) | 458 | static void dma_rx_callback(void *arg) |
460 | { | 459 | { |
461 | struct mxs_auart_port *s = (struct mxs_auart_port *) arg; | 460 | struct mxs_auart_port *s = (struct mxs_auart_port *) arg; |
462 | struct tty_struct *tty = s->port.state->port.tty; | 461 | struct tty_port *port = &s->port.state->port; |
463 | int count; | 462 | int count; |
464 | u32 stat; | 463 | u32 stat; |
465 | 464 | ||
@@ -470,10 +469,10 @@ static void dma_rx_callback(void *arg) | |||
470 | AUART_STAT_PERR | AUART_STAT_FERR); | 469 | AUART_STAT_PERR | AUART_STAT_FERR); |
471 | 470 | ||
472 | count = stat & AUART_STAT_RXCOUNT_MASK; | 471 | count = stat & AUART_STAT_RXCOUNT_MASK; |
473 | tty_insert_flip_string(tty, s->rx_dma_buf, count); | 472 | tty_insert_flip_string(port, s->rx_dma_buf, count); |
474 | 473 | ||
475 | writel(stat, s->port.membase + AUART_STAT); | 474 | writel(stat, s->port.membase + AUART_STAT); |
476 | tty_flip_buffer_push(tty); | 475 | tty_flip_buffer_push(port); |
477 | 476 | ||
478 | /* start the next DMA for RX. */ | 477 | /* start the next DMA for RX. */ |
479 | mxs_auart_dma_prep_rx(s); | 478 | mxs_auart_dma_prep_rx(s); |
@@ -552,7 +551,7 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s) | |||
552 | return 0; | 551 | return 0; |
553 | 552 | ||
554 | /* We do not get the right DMA channels. */ | 553 | /* We do not get the right DMA channels. */ |
555 | if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1) | 554 | if (s->dma_channel_rx == -1 || s->dma_channel_tx == -1) |
556 | return -EINVAL; | 555 | return -EINVAL; |
557 | 556 | ||
558 | /* init for RX */ | 557 | /* init for RX */ |
diff --git a/drivers/tty/serial/netx-serial.c b/drivers/tty/serial/netx-serial.c index d40da78e7c85..b9a40ed70be2 100644 --- a/drivers/tty/serial/netx-serial.c +++ b/drivers/tty/serial/netx-serial.c | |||
@@ -199,7 +199,6 @@ static void netx_txint(struct uart_port *port) | |||
199 | static void netx_rxint(struct uart_port *port) | 199 | static void netx_rxint(struct uart_port *port) |
200 | { | 200 | { |
201 | unsigned char rx, flg, status; | 201 | unsigned char rx, flg, status; |
202 | struct tty_struct *tty = port->state->port.tty; | ||
203 | 202 | ||
204 | while (!(readl(port->membase + UART_FR) & FR_RXFE)) { | 203 | while (!(readl(port->membase + UART_FR) & FR_RXFE)) { |
205 | rx = readl(port->membase + UART_DR); | 204 | rx = readl(port->membase + UART_DR); |
@@ -237,8 +236,7 @@ static void netx_rxint(struct uart_port *port) | |||
237 | uart_insert_char(port, status, SR_OE, rx, flg); | 236 | uart_insert_char(port, status, SR_OE, rx, flg); |
238 | } | 237 | } |
239 | 238 | ||
240 | tty_flip_buffer_push(tty); | 239 | tty_flip_buffer_push(&port->state->port); |
241 | return; | ||
242 | } | 240 | } |
243 | 241 | ||
244 | static irqreturn_t netx_int(int irq, void *dev_id) | 242 | static irqreturn_t netx_int(int irq, void *dev_id) |
diff --git a/drivers/tty/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c index dd4c31d1aee5..77287c54f331 100644 --- a/drivers/tty/serial/nwpserial.c +++ b/drivers/tty/serial/nwpserial.c | |||
@@ -128,7 +128,7 @@ static void nwpserial_config_port(struct uart_port *port, int flags) | |||
128 | static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) | 128 | static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) |
129 | { | 129 | { |
130 | struct nwpserial_port *up = dev_id; | 130 | struct nwpserial_port *up = dev_id; |
131 | struct tty_struct *tty = up->port.state->port.tty; | 131 | struct tty_port *port = &up->port.state->port; |
132 | irqreturn_t ret; | 132 | irqreturn_t ret; |
133 | unsigned int iir; | 133 | unsigned int iir; |
134 | unsigned char ch; | 134 | unsigned char ch; |
@@ -146,10 +146,10 @@ static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) | |||
146 | up->port.icount.rx++; | 146 | up->port.icount.rx++; |
147 | ch = dcr_read(up->dcr_host, UART_RX); | 147 | ch = dcr_read(up->dcr_host, UART_RX); |
148 | if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) | 148 | if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) |
149 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 149 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
150 | } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); | 150 | } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); |
151 | 151 | ||
152 | tty_flip_buffer_push(tty); | 152 | tty_flip_buffer_push(port); |
153 | ret = IRQ_HANDLED; | 153 | ret = IRQ_HANDLED; |
154 | 154 | ||
155 | /* clear interrupt */ | 155 | /* clear interrupt */ |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index e7cae1c2d7d2..d5874605682b 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/serial_reg.h> | 18 | #include <linux/serial_reg.h> |
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_irq.h> | 20 | #include <linux/of_irq.h> |
21 | #include <linux/of_serial.h> | ||
22 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
23 | #include <linux/nwpserial.h> | 22 | #include <linux/nwpserial.h> |
24 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
@@ -45,8 +44,10 @@ void tegra_serial_handle_break(struct uart_port *p) | |||
45 | udelay(1); | 44 | udelay(1); |
46 | } while (1); | 45 | } while (1); |
47 | } | 46 | } |
48 | /* FIXME remove this export when tegra finishes conversion to open firmware */ | 47 | #else |
49 | EXPORT_SYMBOL_GPL(tegra_serial_handle_break); | 48 | static inline void tegra_serial_handle_break(struct uart_port *port) |
49 | { | ||
50 | } | ||
50 | #endif | 51 | #endif |
51 | 52 | ||
52 | /* | 53 | /* |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 57d6b29c039c..4dc41408ecb7 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -59,6 +59,7 @@ | |||
59 | 59 | ||
60 | /* SCR register bitmasks */ | 60 | /* SCR register bitmasks */ |
61 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) | 61 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) |
62 | #define OMAP_UART_SCR_TX_TRIG_GRANU1_MASK (1 << 6) | ||
62 | #define OMAP_UART_SCR_TX_EMPTY (1 << 3) | 63 | #define OMAP_UART_SCR_TX_EMPTY (1 << 3) |
63 | 64 | ||
64 | /* FCR register bitmasks */ | 65 | /* FCR register bitmasks */ |
@@ -232,24 +233,42 @@ static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | |||
232 | } | 233 | } |
233 | 234 | ||
234 | /* | 235 | /* |
236 | * serial_omap_baud_is_mode16 - check if baud rate is MODE16X | ||
237 | * @port: uart port info | ||
238 | * @baud: baudrate for which mode needs to be determined | ||
239 | * | ||
240 | * Returns true if baud rate is MODE16X and false if MODE13X | ||
241 | * Original table in OMAP TRM named "UART Mode Baud Rates, Divisor Values, | ||
242 | * and Error Rates" determines modes not for all common baud rates. | ||
243 | * E.g. for 1000000 baud rate mode must be 16x, but according to that | ||
244 | * table it's determined as 13x. | ||
245 | */ | ||
246 | static bool | ||
247 | serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud) | ||
248 | { | ||
249 | unsigned int n13 = port->uartclk / (13 * baud); | ||
250 | unsigned int n16 = port->uartclk / (16 * baud); | ||
251 | int baudAbsDiff13 = baud - (port->uartclk / (13 * n13)); | ||
252 | int baudAbsDiff16 = baud - (port->uartclk / (16 * n16)); | ||
253 | if(baudAbsDiff13 < 0) | ||
254 | baudAbsDiff13 = -baudAbsDiff13; | ||
255 | if(baudAbsDiff16 < 0) | ||
256 | baudAbsDiff16 = -baudAbsDiff16; | ||
257 | |||
258 | return (baudAbsDiff13 > baudAbsDiff16); | ||
259 | } | ||
260 | |||
261 | /* | ||
235 | * serial_omap_get_divisor - calculate divisor value | 262 | * serial_omap_get_divisor - calculate divisor value |
236 | * @port: uart port info | 263 | * @port: uart port info |
237 | * @baud: baudrate for which divisor needs to be calculated. | 264 | * @baud: baudrate for which divisor needs to be calculated. |
238 | * | ||
239 | * We have written our own function to get the divisor so as to support | ||
240 | * 13x mode. 3Mbps Baudrate as an different divisor. | ||
241 | * Reference OMAP TRM Chapter 17: | ||
242 | * Table 17-1. UART Mode Baud Rates, Divisor Values, and Error Rates | ||
243 | * referring to oversampling - divisor value | ||
244 | * baudrate 460,800 to 3,686,400 all have divisor 13 | ||
245 | * except 3,000,000 which has divisor value 16 | ||
246 | */ | 265 | */ |
247 | static unsigned int | 266 | static unsigned int |
248 | serial_omap_get_divisor(struct uart_port *port, unsigned int baud) | 267 | serial_omap_get_divisor(struct uart_port *port, unsigned int baud) |
249 | { | 268 | { |
250 | unsigned int divisor; | 269 | unsigned int divisor; |
251 | 270 | ||
252 | if (baud > OMAP_MODE13X_SPEED && baud != 3000000) | 271 | if (!serial_omap_baud_is_mode16(port, baud)) |
253 | divisor = 13; | 272 | divisor = 13; |
254 | else | 273 | else |
255 | divisor = 16; | 274 | divisor = 16; |
@@ -302,9 +321,6 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) | |||
302 | struct circ_buf *xmit = &up->port.state->xmit; | 321 | struct circ_buf *xmit = &up->port.state->xmit; |
303 | int count; | 322 | int count; |
304 | 323 | ||
305 | if (!(lsr & UART_LSR_THRE)) | ||
306 | return; | ||
307 | |||
308 | if (up->port.x_char) { | 324 | if (up->port.x_char) { |
309 | serial_out(up, UART_TX, up->port.x_char); | 325 | serial_out(up, UART_TX, up->port.x_char); |
310 | up->port.icount.tx++; | 326 | up->port.icount.tx++; |
@@ -483,7 +499,6 @@ static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) | |||
483 | static irqreturn_t serial_omap_irq(int irq, void *dev_id) | 499 | static irqreturn_t serial_omap_irq(int irq, void *dev_id) |
484 | { | 500 | { |
485 | struct uart_omap_port *up = dev_id; | 501 | struct uart_omap_port *up = dev_id; |
486 | struct tty_struct *tty = up->port.state->port.tty; | ||
487 | unsigned int iir, lsr; | 502 | unsigned int iir, lsr; |
488 | unsigned int type; | 503 | unsigned int type; |
489 | irqreturn_t ret = IRQ_NONE; | 504 | irqreturn_t ret = IRQ_NONE; |
@@ -530,7 +545,7 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) | |||
530 | 545 | ||
531 | spin_unlock(&up->port.lock); | 546 | spin_unlock(&up->port.lock); |
532 | 547 | ||
533 | tty_flip_buffer_push(tty); | 548 | tty_flip_buffer_push(&up->port.state->port); |
534 | 549 | ||
535 | pm_runtime_mark_last_busy(up->dev); | 550 | pm_runtime_mark_last_busy(up->dev); |
536 | pm_runtime_put_autosuspend(up->dev); | 551 | pm_runtime_put_autosuspend(up->dev); |
@@ -776,6 +791,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
776 | cval |= UART_LCR_PARITY; | 791 | cval |= UART_LCR_PARITY; |
777 | if (!(termios->c_cflag & PARODD)) | 792 | if (!(termios->c_cflag & PARODD)) |
778 | cval |= UART_LCR_EPAR; | 793 | cval |= UART_LCR_EPAR; |
794 | if (termios->c_cflag & CMSPAR) | ||
795 | cval |= UART_LCR_SPAR; | ||
779 | 796 | ||
780 | /* | 797 | /* |
781 | * Ask the core to calculate the divisor for us. | 798 | * Ask the core to calculate the divisor for us. |
@@ -845,7 +862,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
845 | serial_out(up, UART_IER, up->ier); | 862 | serial_out(up, UART_IER, up->ier); |
846 | serial_out(up, UART_LCR, cval); /* reset DLAB */ | 863 | serial_out(up, UART_LCR, cval); /* reset DLAB */ |
847 | up->lcr = cval; | 864 | up->lcr = cval; |
848 | up->scr = OMAP_UART_SCR_TX_EMPTY; | 865 | up->scr = 0; |
849 | 866 | ||
850 | /* FIFOs and DMA Settings */ | 867 | /* FIFOs and DMA Settings */ |
851 | 868 | ||
@@ -869,8 +886,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
869 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); | 886 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); |
870 | /* FIFO ENABLE, DMA MODE */ | 887 | /* FIFO ENABLE, DMA MODE */ |
871 | 888 | ||
872 | up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; | ||
873 | |||
874 | /* Set receive FIFO threshold to 16 characters and | 889 | /* Set receive FIFO threshold to 16 characters and |
875 | * transmit FIFO threshold to 16 spaces | 890 | * transmit FIFO threshold to 16 spaces |
876 | */ | 891 | */ |
@@ -915,7 +930,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
915 | serial_out(up, UART_EFR, up->efr); | 930 | serial_out(up, UART_EFR, up->efr); |
916 | serial_out(up, UART_LCR, cval); | 931 | serial_out(up, UART_LCR, cval); |
917 | 932 | ||
918 | if (baud > 230400 && baud != 3000000) | 933 | if (!serial_omap_baud_is_mode16(port, baud)) |
919 | up->mdr1 = UART_OMAP_MDR1_13X_MODE; | 934 | up->mdr1 = UART_OMAP_MDR1_13X_MODE; |
920 | else | 935 | else |
921 | up->mdr1 = UART_OMAP_MDR1_16X_MODE; | 936 | up->mdr1 = UART_OMAP_MDR1_16X_MODE; |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 8318925fbf6b..7a6c989924b3 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -14,18 +14,21 @@ | |||
14 | *along with this program; if not, write to the Free Software | 14 | *along with this program; if not, write to the Free Software |
15 | *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 15 | *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
16 | */ | 16 | */ |
17 | #if defined(CONFIG_SERIAL_PCH_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
18 | #define SUPPORT_SYSRQ | ||
19 | #endif | ||
17 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
18 | #include <linux/serial_reg.h> | 21 | #include <linux/serial_reg.h> |
19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
20 | #include <linux/module.h> | 23 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
25 | #include <linux/console.h> | ||
22 | #include <linux/serial_core.h> | 26 | #include <linux/serial_core.h> |
23 | #include <linux/tty.h> | 27 | #include <linux/tty.h> |
24 | #include <linux/tty_flip.h> | 28 | #include <linux/tty_flip.h> |
25 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
26 | #include <linux/io.h> | 30 | #include <linux/io.h> |
27 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
28 | #include <linux/console.h> | ||
29 | #include <linux/nmi.h> | 32 | #include <linux/nmi.h> |
30 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
31 | 34 | ||
@@ -553,12 +556,26 @@ static int pch_uart_hal_read(struct eg20t_port *priv, unsigned char *buf, | |||
553 | { | 556 | { |
554 | int i; | 557 | int i; |
555 | u8 rbr, lsr; | 558 | u8 rbr, lsr; |
559 | struct uart_port *port = &priv->port; | ||
556 | 560 | ||
557 | lsr = ioread8(priv->membase + UART_LSR); | 561 | lsr = ioread8(priv->membase + UART_LSR); |
558 | for (i = 0, lsr = ioread8(priv->membase + UART_LSR); | 562 | for (i = 0, lsr = ioread8(priv->membase + UART_LSR); |
559 | i < rx_size && lsr & UART_LSR_DR; | 563 | i < rx_size && lsr & (UART_LSR_DR | UART_LSR_BI); |
560 | lsr = ioread8(priv->membase + UART_LSR)) { | 564 | lsr = ioread8(priv->membase + UART_LSR)) { |
561 | rbr = ioread8(priv->membase + PCH_UART_RBR); | 565 | rbr = ioread8(priv->membase + PCH_UART_RBR); |
566 | |||
567 | if (lsr & UART_LSR_BI) { | ||
568 | port->icount.brk++; | ||
569 | if (uart_handle_break(port)) | ||
570 | continue; | ||
571 | } | ||
572 | #ifdef SUPPORT_SYSRQ | ||
573 | if (port->sysrq) { | ||
574 | if (uart_handle_sysrq_char(port, rbr)) | ||
575 | continue; | ||
576 | } | ||
577 | #endif | ||
578 | |||
562 | buf[i++] = rbr; | 579 | buf[i++] = rbr; |
563 | } | 580 | } |
564 | return i; | 581 | return i; |
@@ -591,19 +608,11 @@ static void pch_uart_hal_set_break(struct eg20t_port *priv, int on) | |||
591 | static int push_rx(struct eg20t_port *priv, const unsigned char *buf, | 608 | static int push_rx(struct eg20t_port *priv, const unsigned char *buf, |
592 | int size) | 609 | int size) |
593 | { | 610 | { |
594 | struct uart_port *port; | 611 | struct uart_port *port = &priv->port; |
595 | struct tty_struct *tty; | 612 | struct tty_port *tport = &port->state->port; |
596 | |||
597 | port = &priv->port; | ||
598 | tty = tty_port_tty_get(&port->state->port); | ||
599 | if (!tty) { | ||
600 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | ||
601 | return -EBUSY; | ||
602 | } | ||
603 | 613 | ||
604 | tty_insert_flip_string(tty, buf, size); | 614 | tty_insert_flip_string(tport, buf, size); |
605 | tty_flip_buffer_push(tty); | 615 | tty_flip_buffer_push(tport); |
606 | tty_kref_put(tty); | ||
607 | 616 | ||
608 | return 0; | 617 | return 0; |
609 | } | 618 | } |
@@ -629,15 +638,16 @@ static int dma_push_rx(struct eg20t_port *priv, int size) | |||
629 | struct tty_struct *tty; | 638 | struct tty_struct *tty; |
630 | int room; | 639 | int room; |
631 | struct uart_port *port = &priv->port; | 640 | struct uart_port *port = &priv->port; |
641 | struct tty_port *tport = &port->state->port; | ||
632 | 642 | ||
633 | port = &priv->port; | 643 | port = &priv->port; |
634 | tty = tty_port_tty_get(&port->state->port); | 644 | tty = tty_port_tty_get(tport); |
635 | if (!tty) { | 645 | if (!tty) { |
636 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | 646 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); |
637 | return 0; | 647 | return 0; |
638 | } | 648 | } |
639 | 649 | ||
640 | room = tty_buffer_request_room(tty, size); | 650 | room = tty_buffer_request_room(tport, size); |
641 | 651 | ||
642 | if (room < size) | 652 | if (room < size) |
643 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | 653 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", |
@@ -645,7 +655,7 @@ static int dma_push_rx(struct eg20t_port *priv, int size) | |||
645 | if (!room) | 655 | if (!room) |
646 | return room; | 656 | return room; |
647 | 657 | ||
648 | tty_insert_flip_string(tty, sg_virt(&priv->sg_rx), size); | 658 | tty_insert_flip_string(tport, sg_virt(&priv->sg_rx), size); |
649 | 659 | ||
650 | port->icount.rx += room; | 660 | port->icount.rx += room; |
651 | tty_kref_put(tty); | 661 | tty_kref_put(tty); |
@@ -743,19 +753,12 @@ static void pch_dma_rx_complete(void *arg) | |||
743 | { | 753 | { |
744 | struct eg20t_port *priv = arg; | 754 | struct eg20t_port *priv = arg; |
745 | struct uart_port *port = &priv->port; | 755 | struct uart_port *port = &priv->port; |
746 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
747 | int count; | 756 | int count; |
748 | 757 | ||
749 | if (!tty) { | ||
750 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | ||
751 | return; | ||
752 | } | ||
753 | |||
754 | dma_sync_sg_for_cpu(port->dev, &priv->sg_rx, 1, DMA_FROM_DEVICE); | 758 | dma_sync_sg_for_cpu(port->dev, &priv->sg_rx, 1, DMA_FROM_DEVICE); |
755 | count = dma_push_rx(priv, priv->trigger_level); | 759 | count = dma_push_rx(priv, priv->trigger_level); |
756 | if (count) | 760 | if (count) |
757 | tty_flip_buffer_push(tty); | 761 | tty_flip_buffer_push(&port->state->port); |
758 | tty_kref_put(tty); | ||
759 | async_tx_ack(priv->desc_rx); | 762 | async_tx_ack(priv->desc_rx); |
760 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | | 763 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | |
761 | PCH_UART_HAL_RX_ERR_INT); | 764 | PCH_UART_HAL_RX_ERR_INT); |
@@ -1037,23 +1040,33 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) | |||
1037 | 1040 | ||
1038 | static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) | 1041 | static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) |
1039 | { | 1042 | { |
1040 | u8 fcr = ioread8(priv->membase + UART_FCR); | 1043 | struct uart_port *port = &priv->port; |
1041 | 1044 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | |
1042 | /* Reset FIFO */ | 1045 | char *error_msg[5] = {}; |
1043 | fcr |= UART_FCR_CLEAR_RCVR; | 1046 | int i = 0; |
1044 | iowrite8(fcr, priv->membase + UART_FCR); | ||
1045 | 1047 | ||
1046 | if (lsr & PCH_UART_LSR_ERR) | 1048 | if (lsr & PCH_UART_LSR_ERR) |
1047 | dev_err(&priv->pdev->dev, "Error data in FIFO\n"); | 1049 | error_msg[i++] = "Error data in FIFO\n"; |
1048 | 1050 | ||
1049 | if (lsr & UART_LSR_FE) | 1051 | if (lsr & UART_LSR_FE) { |
1050 | dev_err(&priv->pdev->dev, "Framing Error\n"); | 1052 | port->icount.frame++; |
1053 | error_msg[i++] = " Framing Error\n"; | ||
1054 | } | ||
1051 | 1055 | ||
1052 | if (lsr & UART_LSR_PE) | 1056 | if (lsr & UART_LSR_PE) { |
1053 | dev_err(&priv->pdev->dev, "Parity Error\n"); | 1057 | port->icount.parity++; |
1058 | error_msg[i++] = " Parity Error\n"; | ||
1059 | } | ||
1054 | 1060 | ||
1055 | if (lsr & UART_LSR_OE) | 1061 | if (lsr & UART_LSR_OE) { |
1056 | dev_err(&priv->pdev->dev, "Overrun Error\n"); | 1062 | port->icount.overrun++; |
1063 | error_msg[i++] = " Overrun Error\n"; | ||
1064 | } | ||
1065 | |||
1066 | if (tty == NULL) { | ||
1067 | for (i = 0; error_msg[i] != NULL; i++) | ||
1068 | dev_err(&priv->pdev->dev, error_msg[i]); | ||
1069 | } | ||
1057 | } | 1070 | } |
1058 | 1071 | ||
1059 | static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) | 1072 | static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) |
@@ -1564,7 +1577,8 @@ pch_console_write(struct console *co, const char *s, unsigned int count) | |||
1564 | 1577 | ||
1565 | local_irq_save(flags); | 1578 | local_irq_save(flags); |
1566 | if (priv->port.sysrq) { | 1579 | if (priv->port.sysrq) { |
1567 | spin_lock(&priv->lock); | 1580 | /* call to uart_handle_sysrq_char already took the priv lock */ |
1581 | priv_locked = 0; | ||
1568 | /* serial8250_handle_port() already took the port lock */ | 1582 | /* serial8250_handle_port() already took the port lock */ |
1569 | port_locked = 0; | 1583 | port_locked = 0; |
1570 | } else if (oops_in_progress) { | 1584 | } else if (oops_in_progress) { |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 333c8d012b0e..b1785f58b6e3 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -227,19 +227,19 @@ static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable) | |||
227 | write_zsreg(uap, R1, uap->curregs[1]); | 227 | write_zsreg(uap, R1, uap->curregs[1]); |
228 | } | 228 | } |
229 | 229 | ||
230 | static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | 230 | static bool pmz_receive_chars(struct uart_pmac_port *uap) |
231 | { | 231 | { |
232 | struct tty_struct *tty = NULL; | 232 | struct tty_port *port; |
233 | unsigned char ch, r1, drop, error, flag; | 233 | unsigned char ch, r1, drop, error, flag; |
234 | int loops = 0; | 234 | int loops = 0; |
235 | 235 | ||
236 | /* Sanity check, make sure the old bug is no longer happening */ | 236 | /* Sanity check, make sure the old bug is no longer happening */ |
237 | if (uap->port.state == NULL || uap->port.state->port.tty == NULL) { | 237 | if (uap->port.state == NULL) { |
238 | WARN_ON(1); | 238 | WARN_ON(1); |
239 | (void)read_zsdata(uap); | 239 | (void)read_zsdata(uap); |
240 | return NULL; | 240 | return false; |
241 | } | 241 | } |
242 | tty = uap->port.state->port.tty; | 242 | port = &uap->port.state->port; |
243 | 243 | ||
244 | while (1) { | 244 | while (1) { |
245 | error = 0; | 245 | error = 0; |
@@ -309,10 +309,10 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
309 | 309 | ||
310 | if (uap->port.ignore_status_mask == 0xff || | 310 | if (uap->port.ignore_status_mask == 0xff || |
311 | (r1 & uap->port.ignore_status_mask) == 0) { | 311 | (r1 & uap->port.ignore_status_mask) == 0) { |
312 | tty_insert_flip_char(tty, ch, flag); | 312 | tty_insert_flip_char(port, ch, flag); |
313 | } | 313 | } |
314 | if (r1 & Rx_OVR) | 314 | if (r1 & Rx_OVR) |
315 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 315 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
316 | next_char: | 316 | next_char: |
317 | /* We can get stuck in an infinite loop getting char 0 when the | 317 | /* We can get stuck in an infinite loop getting char 0 when the |
318 | * line is in a wrong HW state, we break that here. | 318 | * line is in a wrong HW state, we break that here. |
@@ -328,11 +328,11 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
328 | break; | 328 | break; |
329 | } | 329 | } |
330 | 330 | ||
331 | return tty; | 331 | return true; |
332 | flood: | 332 | flood: |
333 | pmz_interrupt_control(uap, 0); | 333 | pmz_interrupt_control(uap, 0); |
334 | pmz_error("pmz: rx irq flood !\n"); | 334 | pmz_error("pmz: rx irq flood !\n"); |
335 | return tty; | 335 | return true; |
336 | } | 336 | } |
337 | 337 | ||
338 | static void pmz_status_handle(struct uart_pmac_port *uap) | 338 | static void pmz_status_handle(struct uart_pmac_port *uap) |
@@ -453,7 +453,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
453 | struct uart_pmac_port *uap_a; | 453 | struct uart_pmac_port *uap_a; |
454 | struct uart_pmac_port *uap_b; | 454 | struct uart_pmac_port *uap_b; |
455 | int rc = IRQ_NONE; | 455 | int rc = IRQ_NONE; |
456 | struct tty_struct *tty; | 456 | bool push; |
457 | u8 r3; | 457 | u8 r3; |
458 | 458 | ||
459 | uap_a = pmz_get_port_A(uap); | 459 | uap_a = pmz_get_port_A(uap); |
@@ -466,7 +466,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
466 | pmz_debug("irq, r3: %x\n", r3); | 466 | pmz_debug("irq, r3: %x\n", r3); |
467 | #endif | 467 | #endif |
468 | /* Channel A */ | 468 | /* Channel A */ |
469 | tty = NULL; | 469 | push = false; |
470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
471 | if (!ZS_IS_OPEN(uap_a)) { | 471 | if (!ZS_IS_OPEN(uap_a)) { |
472 | pmz_debug("ChanA interrupt while not open !\n"); | 472 | pmz_debug("ChanA interrupt while not open !\n"); |
@@ -477,21 +477,21 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
477 | if (r3 & CHAEXT) | 477 | if (r3 & CHAEXT) |
478 | pmz_status_handle(uap_a); | 478 | pmz_status_handle(uap_a); |
479 | if (r3 & CHARxIP) | 479 | if (r3 & CHARxIP) |
480 | tty = pmz_receive_chars(uap_a); | 480 | push = pmz_receive_chars(uap_a); |
481 | if (r3 & CHATxIP) | 481 | if (r3 & CHATxIP) |
482 | pmz_transmit_chars(uap_a); | 482 | pmz_transmit_chars(uap_a); |
483 | rc = IRQ_HANDLED; | 483 | rc = IRQ_HANDLED; |
484 | } | 484 | } |
485 | skip_a: | 485 | skip_a: |
486 | spin_unlock(&uap_a->port.lock); | 486 | spin_unlock(&uap_a->port.lock); |
487 | if (tty != NULL) | 487 | if (push) |
488 | tty_flip_buffer_push(tty); | 488 | tty_flip_buffer_push(&uap->port.state->port); |
489 | 489 | ||
490 | if (!uap_b) | 490 | if (!uap_b) |
491 | goto out; | 491 | goto out; |
492 | 492 | ||
493 | spin_lock(&uap_b->port.lock); | 493 | spin_lock(&uap_b->port.lock); |
494 | tty = NULL; | 494 | push = false; |
495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
496 | if (!ZS_IS_OPEN(uap_b)) { | 496 | if (!ZS_IS_OPEN(uap_b)) { |
497 | pmz_debug("ChanB interrupt while not open !\n"); | 497 | pmz_debug("ChanB interrupt while not open !\n"); |
@@ -502,15 +502,15 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
502 | if (r3 & CHBEXT) | 502 | if (r3 & CHBEXT) |
503 | pmz_status_handle(uap_b); | 503 | pmz_status_handle(uap_b); |
504 | if (r3 & CHBRxIP) | 504 | if (r3 & CHBRxIP) |
505 | tty = pmz_receive_chars(uap_b); | 505 | push = pmz_receive_chars(uap_b); |
506 | if (r3 & CHBTxIP) | 506 | if (r3 & CHBTxIP) |
507 | pmz_transmit_chars(uap_b); | 507 | pmz_transmit_chars(uap_b); |
508 | rc = IRQ_HANDLED; | 508 | rc = IRQ_HANDLED; |
509 | } | 509 | } |
510 | skip_b: | 510 | skip_b: |
511 | spin_unlock(&uap_b->port.lock); | 511 | spin_unlock(&uap_b->port.lock); |
512 | if (tty != NULL) | 512 | if (push) |
513 | tty_flip_buffer_push(tty); | 513 | tty_flip_buffer_push(&uap->port.state->port); |
514 | 514 | ||
515 | out: | 515 | out: |
516 | return rc; | 516 | return rc; |
diff --git a/drivers/tty/serial/pnx8xxx_uart.c b/drivers/tty/serial/pnx8xxx_uart.c index 0aa75a97531c..7e277a5384a7 100644 --- a/drivers/tty/serial/pnx8xxx_uart.c +++ b/drivers/tty/serial/pnx8xxx_uart.c | |||
@@ -181,7 +181,6 @@ static void pnx8xxx_enable_ms(struct uart_port *port) | |||
181 | 181 | ||
182 | static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) | 182 | static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) |
183 | { | 183 | { |
184 | struct tty_struct *tty = sport->port.state->port.tty; | ||
185 | unsigned int status, ch, flg; | 184 | unsigned int status, ch, flg; |
186 | 185 | ||
187 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | | 186 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | |
@@ -238,7 +237,7 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) | |||
238 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | | 237 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | |
239 | ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); | 238 | ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); |
240 | } | 239 | } |
241 | tty_flip_buffer_push(tty); | 240 | tty_flip_buffer_push(&sport->port.state->port); |
242 | } | 241 | } |
243 | 242 | ||
244 | static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) | 243 | static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 2764828251f5..05f504e0c271 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
@@ -98,7 +98,6 @@ static void serial_pxa_stop_rx(struct uart_port *port) | |||
98 | 98 | ||
99 | static inline void receive_chars(struct uart_pxa_port *up, int *status) | 99 | static inline void receive_chars(struct uart_pxa_port *up, int *status) |
100 | { | 100 | { |
101 | struct tty_struct *tty = up->port.state->port.tty; | ||
102 | unsigned int ch, flag; | 101 | unsigned int ch, flag; |
103 | int max_count = 256; | 102 | int max_count = 256; |
104 | 103 | ||
@@ -168,7 +167,7 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) | |||
168 | ignore_char: | 167 | ignore_char: |
169 | *status = serial_in(up, UART_LSR); | 168 | *status = serial_in(up, UART_LSR); |
170 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 169 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
171 | tty_flip_buffer_push(tty); | 170 | tty_flip_buffer_push(&up->port.state->port); |
172 | 171 | ||
173 | /* work around Errata #20 according to | 172 | /* work around Errata #20 according to |
174 | * Intel(R) PXA27x Processor Family | 173 | * Intel(R) PXA27x Processor Family |
@@ -673,8 +672,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
673 | unsigned long flags; | 672 | unsigned long flags; |
674 | int locked = 1; | 673 | int locked = 1; |
675 | 674 | ||
676 | clk_prepare_enable(up->clk); | 675 | clk_enable(up->clk); |
677 | |||
678 | local_irq_save(flags); | 676 | local_irq_save(flags); |
679 | if (up->port.sysrq) | 677 | if (up->port.sysrq) |
680 | locked = 0; | 678 | locked = 0; |
@@ -701,8 +699,8 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
701 | if (locked) | 699 | if (locked) |
702 | spin_unlock(&up->port.lock); | 700 | spin_unlock(&up->port.lock); |
703 | local_irq_restore(flags); | 701 | local_irq_restore(flags); |
702 | clk_disable(up->clk); | ||
704 | 703 | ||
705 | clk_disable_unprepare(up->clk); | ||
706 | } | 704 | } |
707 | 705 | ||
708 | #ifdef CONFIG_CONSOLE_POLL | 706 | #ifdef CONFIG_CONSOLE_POLL |
@@ -899,6 +897,12 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
899 | goto err_free; | 897 | goto err_free; |
900 | } | 898 | } |
901 | 899 | ||
900 | ret = clk_prepare(sport->clk); | ||
901 | if (ret) { | ||
902 | clk_put(sport->clk); | ||
903 | goto err_free; | ||
904 | } | ||
905 | |||
902 | sport->port.type = PORT_PXA; | 906 | sport->port.type = PORT_PXA; |
903 | sport->port.iotype = UPIO_MEM; | 907 | sport->port.iotype = UPIO_MEM; |
904 | sport->port.mapbase = mmres->start; | 908 | sport->port.mapbase = mmres->start; |
@@ -930,6 +934,7 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
930 | return 0; | 934 | return 0; |
931 | 935 | ||
932 | err_clk: | 936 | err_clk: |
937 | clk_unprepare(sport->clk); | ||
933 | clk_put(sport->clk); | 938 | clk_put(sport->clk); |
934 | err_free: | 939 | err_free: |
935 | kfree(sport); | 940 | kfree(sport); |
@@ -943,6 +948,8 @@ static int serial_pxa_remove(struct platform_device *dev) | |||
943 | platform_set_drvdata(dev, NULL); | 948 | platform_set_drvdata(dev, NULL); |
944 | 949 | ||
945 | uart_remove_one_port(&serial_pxa_reg, &sport->port); | 950 | uart_remove_one_port(&serial_pxa_reg, &sport->port); |
951 | |||
952 | clk_unprepare(sport->clk); | ||
946 | clk_put(sport->clk); | 953 | clk_put(sport->clk); |
947 | kfree(sport); | 954 | kfree(sport); |
948 | 955 | ||
diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c new file mode 100644 index 000000000000..a314a943f124 --- /dev/null +++ b/drivers/tty/serial/rp2.c | |||
@@ -0,0 +1,885 @@ | |||
1 | /* | ||
2 | * Driver for Comtrol RocketPort EXPRESS/INFINITY cards | ||
3 | * | ||
4 | * Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com> | ||
5 | * | ||
6 | * Inspired by, and loosely based on: | ||
7 | * | ||
8 | * ar933x_uart.c | ||
9 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
10 | * | ||
11 | * rocketport_infinity_express-linux-1.20.tar.gz | ||
12 | * Copyright (C) 2004-2011 Comtrol, Inc. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify it | ||
15 | * under the terms of the GNU General Public License version 2 as published | ||
16 | * by the Free Software Foundation. | ||
17 | */ | ||
18 | |||
19 | #include <linux/bitops.h> | ||
20 | #include <linux/compiler.h> | ||
21 | #include <linux/completion.h> | ||
22 | #include <linux/console.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/firmware.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/log2.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/sysrq.h> | ||
37 | #include <linux/tty.h> | ||
38 | #include <linux/tty_flip.h> | ||
39 | #include <linux/types.h> | ||
40 | |||
41 | #define DRV_NAME "rp2" | ||
42 | |||
43 | #define RP2_FW_NAME "rp2.fw" | ||
44 | #define RP2_UCODE_BYTES 0x3f | ||
45 | |||
46 | #define PORTS_PER_ASIC 16 | ||
47 | #define ALL_PORTS_MASK (BIT(PORTS_PER_ASIC) - 1) | ||
48 | |||
49 | #define UART_CLOCK 44236800 | ||
50 | #define DEFAULT_BAUD_DIV (UART_CLOCK / (9600 * 16)) | ||
51 | #define FIFO_SIZE 512 | ||
52 | |||
53 | /* BAR0 registers */ | ||
54 | #define RP2_FPGA_CTL0 0x110 | ||
55 | #define RP2_FPGA_CTL1 0x11c | ||
56 | #define RP2_IRQ_MASK 0x1ec | ||
57 | #define RP2_IRQ_MASK_EN_m BIT(0) | ||
58 | #define RP2_IRQ_STATUS 0x1f0 | ||
59 | |||
60 | /* BAR1 registers */ | ||
61 | #define RP2_ASIC_SPACING 0x1000 | ||
62 | #define RP2_ASIC_OFFSET(i) ((i) << ilog2(RP2_ASIC_SPACING)) | ||
63 | |||
64 | #define RP2_PORT_BASE 0x000 | ||
65 | #define RP2_PORT_SPACING 0x040 | ||
66 | |||
67 | #define RP2_UCODE_BASE 0x400 | ||
68 | #define RP2_UCODE_SPACING 0x80 | ||
69 | |||
70 | #define RP2_CLK_PRESCALER 0xc00 | ||
71 | #define RP2_CH_IRQ_STAT 0xc04 | ||
72 | #define RP2_CH_IRQ_MASK 0xc08 | ||
73 | #define RP2_ASIC_IRQ 0xd00 | ||
74 | #define RP2_ASIC_IRQ_EN_m BIT(20) | ||
75 | #define RP2_GLOBAL_CMD 0xd0c | ||
76 | #define RP2_ASIC_CFG 0xd04 | ||
77 | |||
78 | /* port registers */ | ||
79 | #define RP2_DATA_DWORD 0x000 | ||
80 | |||
81 | #define RP2_DATA_BYTE 0x008 | ||
82 | #define RP2_DATA_BYTE_ERR_PARITY_m BIT(8) | ||
83 | #define RP2_DATA_BYTE_ERR_OVERRUN_m BIT(9) | ||
84 | #define RP2_DATA_BYTE_ERR_FRAMING_m BIT(10) | ||
85 | #define RP2_DATA_BYTE_BREAK_m BIT(11) | ||
86 | |||
87 | /* This lets uart_insert_char() drop bytes received on a !CREAD port */ | ||
88 | #define RP2_DUMMY_READ BIT(16) | ||
89 | |||
90 | #define RP2_DATA_BYTE_EXCEPTION_MASK (RP2_DATA_BYTE_ERR_PARITY_m | \ | ||
91 | RP2_DATA_BYTE_ERR_OVERRUN_m | \ | ||
92 | RP2_DATA_BYTE_ERR_FRAMING_m | \ | ||
93 | RP2_DATA_BYTE_BREAK_m) | ||
94 | |||
95 | #define RP2_RX_FIFO_COUNT 0x00c | ||
96 | #define RP2_TX_FIFO_COUNT 0x00e | ||
97 | |||
98 | #define RP2_CHAN_STAT 0x010 | ||
99 | #define RP2_CHAN_STAT_RXDATA_m BIT(0) | ||
100 | #define RP2_CHAN_STAT_DCD_m BIT(3) | ||
101 | #define RP2_CHAN_STAT_DSR_m BIT(4) | ||
102 | #define RP2_CHAN_STAT_CTS_m BIT(5) | ||
103 | #define RP2_CHAN_STAT_RI_m BIT(6) | ||
104 | #define RP2_CHAN_STAT_OVERRUN_m BIT(13) | ||
105 | #define RP2_CHAN_STAT_DSR_CHANGED_m BIT(16) | ||
106 | #define RP2_CHAN_STAT_CTS_CHANGED_m BIT(17) | ||
107 | #define RP2_CHAN_STAT_CD_CHANGED_m BIT(18) | ||
108 | #define RP2_CHAN_STAT_RI_CHANGED_m BIT(22) | ||
109 | #define RP2_CHAN_STAT_TXEMPTY_m BIT(25) | ||
110 | |||
111 | #define RP2_CHAN_STAT_MS_CHANGED_MASK (RP2_CHAN_STAT_DSR_CHANGED_m | \ | ||
112 | RP2_CHAN_STAT_CTS_CHANGED_m | \ | ||
113 | RP2_CHAN_STAT_CD_CHANGED_m | \ | ||
114 | RP2_CHAN_STAT_RI_CHANGED_m) | ||
115 | |||
116 | #define RP2_TXRX_CTL 0x014 | ||
117 | #define RP2_TXRX_CTL_MSRIRQ_m BIT(0) | ||
118 | #define RP2_TXRX_CTL_RXIRQ_m BIT(2) | ||
119 | #define RP2_TXRX_CTL_RX_TRIG_s 3 | ||
120 | #define RP2_TXRX_CTL_RX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
121 | #define RP2_TXRX_CTL_RX_TRIG_1 (0x1 << RP2_TXRX_CTL_RX_TRIG_s) | ||
122 | #define RP2_TXRX_CTL_RX_TRIG_256 (0x2 << RP2_TXRX_CTL_RX_TRIG_s) | ||
123 | #define RP2_TXRX_CTL_RX_TRIG_448 (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
124 | #define RP2_TXRX_CTL_RX_EN_m BIT(5) | ||
125 | #define RP2_TXRX_CTL_RTSFLOW_m BIT(6) | ||
126 | #define RP2_TXRX_CTL_DTRFLOW_m BIT(7) | ||
127 | #define RP2_TXRX_CTL_TX_TRIG_s 16 | ||
128 | #define RP2_TXRX_CTL_TX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
129 | #define RP2_TXRX_CTL_DSRFLOW_m BIT(18) | ||
130 | #define RP2_TXRX_CTL_TXIRQ_m BIT(19) | ||
131 | #define RP2_TXRX_CTL_CTSFLOW_m BIT(23) | ||
132 | #define RP2_TXRX_CTL_TX_EN_m BIT(24) | ||
133 | #define RP2_TXRX_CTL_RTS_m BIT(25) | ||
134 | #define RP2_TXRX_CTL_DTR_m BIT(26) | ||
135 | #define RP2_TXRX_CTL_LOOP_m BIT(27) | ||
136 | #define RP2_TXRX_CTL_BREAK_m BIT(28) | ||
137 | #define RP2_TXRX_CTL_CMSPAR_m BIT(29) | ||
138 | #define RP2_TXRX_CTL_nPARODD_m BIT(30) | ||
139 | #define RP2_TXRX_CTL_PARENB_m BIT(31) | ||
140 | |||
141 | #define RP2_UART_CTL 0x018 | ||
142 | #define RP2_UART_CTL_MODE_s 0 | ||
143 | #define RP2_UART_CTL_MODE_m (0x7 << RP2_UART_CTL_MODE_s) | ||
144 | #define RP2_UART_CTL_MODE_rs232 (0x1 << RP2_UART_CTL_MODE_s) | ||
145 | #define RP2_UART_CTL_FLUSH_RX_m BIT(3) | ||
146 | #define RP2_UART_CTL_FLUSH_TX_m BIT(4) | ||
147 | #define RP2_UART_CTL_RESET_CH_m BIT(5) | ||
148 | #define RP2_UART_CTL_XMIT_EN_m BIT(6) | ||
149 | #define RP2_UART_CTL_DATABITS_s 8 | ||
150 | #define RP2_UART_CTL_DATABITS_m (0x3 << RP2_UART_CTL_DATABITS_s) | ||
151 | #define RP2_UART_CTL_DATABITS_8 (0x3 << RP2_UART_CTL_DATABITS_s) | ||
152 | #define RP2_UART_CTL_DATABITS_7 (0x2 << RP2_UART_CTL_DATABITS_s) | ||
153 | #define RP2_UART_CTL_DATABITS_6 (0x1 << RP2_UART_CTL_DATABITS_s) | ||
154 | #define RP2_UART_CTL_DATABITS_5 (0x0 << RP2_UART_CTL_DATABITS_s) | ||
155 | #define RP2_UART_CTL_STOPBITS_m BIT(10) | ||
156 | |||
157 | #define RP2_BAUD 0x01c | ||
158 | |||
159 | /* ucode registers */ | ||
160 | #define RP2_TX_SWFLOW 0x02 | ||
161 | #define RP2_TX_SWFLOW_ena 0x81 | ||
162 | #define RP2_TX_SWFLOW_dis 0x9d | ||
163 | |||
164 | #define RP2_RX_SWFLOW 0x0c | ||
165 | #define RP2_RX_SWFLOW_ena 0x81 | ||
166 | #define RP2_RX_SWFLOW_dis 0x8d | ||
167 | |||
168 | #define RP2_RX_FIFO 0x37 | ||
169 | #define RP2_RX_FIFO_ena 0x08 | ||
170 | #define RP2_RX_FIFO_dis 0x81 | ||
171 | |||
172 | static struct uart_driver rp2_uart_driver = { | ||
173 | .owner = THIS_MODULE, | ||
174 | .driver_name = DRV_NAME, | ||
175 | .dev_name = "ttyRP", | ||
176 | .nr = CONFIG_SERIAL_RP2_NR_UARTS, | ||
177 | }; | ||
178 | |||
179 | struct rp2_card; | ||
180 | |||
181 | struct rp2_uart_port { | ||
182 | struct uart_port port; | ||
183 | int idx; | ||
184 | int ignore_rx; | ||
185 | struct rp2_card *card; | ||
186 | void __iomem *asic_base; | ||
187 | void __iomem *base; | ||
188 | void __iomem *ucode; | ||
189 | }; | ||
190 | |||
191 | struct rp2_card { | ||
192 | struct pci_dev *pdev; | ||
193 | struct rp2_uart_port *ports; | ||
194 | int n_ports; | ||
195 | int initialized_ports; | ||
196 | int minor_start; | ||
197 | int smpte; | ||
198 | void __iomem *bar0; | ||
199 | void __iomem *bar1; | ||
200 | spinlock_t card_lock; | ||
201 | struct completion fw_loaded; | ||
202 | }; | ||
203 | |||
204 | #define RP_ID(prod) PCI_VDEVICE(RP, (prod)) | ||
205 | #define RP_CAP(ports, smpte) (((ports) << 8) | ((smpte) << 0)) | ||
206 | |||
207 | static inline void rp2_decode_cap(const struct pci_device_id *id, | ||
208 | int *ports, int *smpte) | ||
209 | { | ||
210 | *ports = id->driver_data >> 8; | ||
211 | *smpte = id->driver_data & 0xff; | ||
212 | } | ||
213 | |||
214 | static DEFINE_SPINLOCK(rp2_minor_lock); | ||
215 | static int rp2_minor_next; | ||
216 | |||
217 | static int rp2_alloc_ports(int n_ports) | ||
218 | { | ||
219 | int ret = -ENOSPC; | ||
220 | |||
221 | spin_lock(&rp2_minor_lock); | ||
222 | if (rp2_minor_next + n_ports <= CONFIG_SERIAL_RP2_NR_UARTS) { | ||
223 | /* sorry, no support for hot unplugging individual cards */ | ||
224 | ret = rp2_minor_next; | ||
225 | rp2_minor_next += n_ports; | ||
226 | } | ||
227 | spin_unlock(&rp2_minor_lock); | ||
228 | |||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | static inline struct rp2_uart_port *port_to_up(struct uart_port *port) | ||
233 | { | ||
234 | return container_of(port, struct rp2_uart_port, port); | ||
235 | } | ||
236 | |||
237 | static void rp2_rmw(struct rp2_uart_port *up, int reg, | ||
238 | u32 clr_bits, u32 set_bits) | ||
239 | { | ||
240 | u32 tmp = readl(up->base + reg); | ||
241 | tmp &= ~clr_bits; | ||
242 | tmp |= set_bits; | ||
243 | writel(tmp, up->base + reg); | ||
244 | } | ||
245 | |||
246 | static void rp2_rmw_clr(struct rp2_uart_port *up, int reg, u32 val) | ||
247 | { | ||
248 | rp2_rmw(up, reg, val, 0); | ||
249 | } | ||
250 | |||
251 | static void rp2_rmw_set(struct rp2_uart_port *up, int reg, u32 val) | ||
252 | { | ||
253 | rp2_rmw(up, reg, 0, val); | ||
254 | } | ||
255 | |||
256 | static void rp2_mask_ch_irq(struct rp2_uart_port *up, int ch_num, | ||
257 | int is_enabled) | ||
258 | { | ||
259 | unsigned long flags, irq_mask; | ||
260 | |||
261 | spin_lock_irqsave(&up->card->card_lock, flags); | ||
262 | |||
263 | irq_mask = readl(up->asic_base + RP2_CH_IRQ_MASK); | ||
264 | if (is_enabled) | ||
265 | irq_mask &= ~BIT(ch_num); | ||
266 | else | ||
267 | irq_mask |= BIT(ch_num); | ||
268 | writel(irq_mask, up->asic_base + RP2_CH_IRQ_MASK); | ||
269 | |||
270 | spin_unlock_irqrestore(&up->card->card_lock, flags); | ||
271 | } | ||
272 | |||
273 | static unsigned int rp2_uart_tx_empty(struct uart_port *port) | ||
274 | { | ||
275 | struct rp2_uart_port *up = port_to_up(port); | ||
276 | unsigned long tx_fifo_bytes, flags; | ||
277 | |||
278 | /* | ||
279 | * This should probably check the transmitter, not the FIFO. | ||
280 | * But the TXEMPTY bit doesn't seem to work unless the TX IRQ is | ||
281 | * enabled. | ||
282 | */ | ||
283 | spin_lock_irqsave(&up->port.lock, flags); | ||
284 | tx_fifo_bytes = readw(up->base + RP2_TX_FIFO_COUNT); | ||
285 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
286 | |||
287 | return tx_fifo_bytes ? 0 : TIOCSER_TEMT; | ||
288 | } | ||
289 | |||
290 | static unsigned int rp2_uart_get_mctrl(struct uart_port *port) | ||
291 | { | ||
292 | struct rp2_uart_port *up = port_to_up(port); | ||
293 | u32 status; | ||
294 | |||
295 | status = readl(up->base + RP2_CHAN_STAT); | ||
296 | return ((status & RP2_CHAN_STAT_DCD_m) ? TIOCM_CAR : 0) | | ||
297 | ((status & RP2_CHAN_STAT_DSR_m) ? TIOCM_DSR : 0) | | ||
298 | ((status & RP2_CHAN_STAT_CTS_m) ? TIOCM_CTS : 0) | | ||
299 | ((status & RP2_CHAN_STAT_RI_m) ? TIOCM_RI : 0); | ||
300 | } | ||
301 | |||
302 | static void rp2_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
303 | { | ||
304 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, | ||
305 | RP2_TXRX_CTL_DTR_m | RP2_TXRX_CTL_RTS_m | RP2_TXRX_CTL_LOOP_m, | ||
306 | ((mctrl & TIOCM_DTR) ? RP2_TXRX_CTL_DTR_m : 0) | | ||
307 | ((mctrl & TIOCM_RTS) ? RP2_TXRX_CTL_RTS_m : 0) | | ||
308 | ((mctrl & TIOCM_LOOP) ? RP2_TXRX_CTL_LOOP_m : 0)); | ||
309 | } | ||
310 | |||
311 | static void rp2_uart_start_tx(struct uart_port *port) | ||
312 | { | ||
313 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); | ||
314 | } | ||
315 | |||
316 | static void rp2_uart_stop_tx(struct uart_port *port) | ||
317 | { | ||
318 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); | ||
319 | } | ||
320 | |||
321 | static void rp2_uart_stop_rx(struct uart_port *port) | ||
322 | { | ||
323 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_RXIRQ_m); | ||
324 | } | ||
325 | |||
326 | static void rp2_uart_break_ctl(struct uart_port *port, int break_state) | ||
327 | { | ||
328 | unsigned long flags; | ||
329 | |||
330 | spin_lock_irqsave(&port->lock, flags); | ||
331 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_BREAK_m, | ||
332 | break_state ? RP2_TXRX_CTL_BREAK_m : 0); | ||
333 | spin_unlock_irqrestore(&port->lock, flags); | ||
334 | } | ||
335 | |||
336 | static void rp2_uart_enable_ms(struct uart_port *port) | ||
337 | { | ||
338 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m); | ||
339 | } | ||
340 | |||
341 | static void __rp2_uart_set_termios(struct rp2_uart_port *up, | ||
342 | unsigned long cfl, | ||
343 | unsigned long ifl, | ||
344 | unsigned int baud_div) | ||
345 | { | ||
346 | /* baud rate divisor (calculated elsewhere). 0 = divide-by-1 */ | ||
347 | writew(baud_div - 1, up->base + RP2_BAUD); | ||
348 | |||
349 | /* data bits and stop bits */ | ||
350 | rp2_rmw(up, RP2_UART_CTL, | ||
351 | RP2_UART_CTL_STOPBITS_m | RP2_UART_CTL_DATABITS_m, | ||
352 | ((cfl & CSTOPB) ? RP2_UART_CTL_STOPBITS_m : 0) | | ||
353 | (((cfl & CSIZE) == CS8) ? RP2_UART_CTL_DATABITS_8 : 0) | | ||
354 | (((cfl & CSIZE) == CS7) ? RP2_UART_CTL_DATABITS_7 : 0) | | ||
355 | (((cfl & CSIZE) == CS6) ? RP2_UART_CTL_DATABITS_6 : 0) | | ||
356 | (((cfl & CSIZE) == CS5) ? RP2_UART_CTL_DATABITS_5 : 0)); | ||
357 | |||
358 | /* parity and hardware flow control */ | ||
359 | rp2_rmw(up, RP2_TXRX_CTL, | ||
360 | RP2_TXRX_CTL_PARENB_m | RP2_TXRX_CTL_nPARODD_m | | ||
361 | RP2_TXRX_CTL_CMSPAR_m | RP2_TXRX_CTL_DTRFLOW_m | | ||
362 | RP2_TXRX_CTL_DSRFLOW_m | RP2_TXRX_CTL_RTSFLOW_m | | ||
363 | RP2_TXRX_CTL_CTSFLOW_m, | ||
364 | ((cfl & PARENB) ? RP2_TXRX_CTL_PARENB_m : 0) | | ||
365 | ((cfl & PARODD) ? 0 : RP2_TXRX_CTL_nPARODD_m) | | ||
366 | ((cfl & CMSPAR) ? RP2_TXRX_CTL_CMSPAR_m : 0) | | ||
367 | ((cfl & CRTSCTS) ? (RP2_TXRX_CTL_RTSFLOW_m | | ||
368 | RP2_TXRX_CTL_CTSFLOW_m) : 0)); | ||
369 | |||
370 | /* XON/XOFF software flow control */ | ||
371 | writeb((ifl & IXON) ? RP2_TX_SWFLOW_ena : RP2_TX_SWFLOW_dis, | ||
372 | up->ucode + RP2_TX_SWFLOW); | ||
373 | writeb((ifl & IXOFF) ? RP2_RX_SWFLOW_ena : RP2_RX_SWFLOW_dis, | ||
374 | up->ucode + RP2_RX_SWFLOW); | ||
375 | } | ||
376 | |||
377 | static void rp2_uart_set_termios(struct uart_port *port, | ||
378 | struct ktermios *new, | ||
379 | struct ktermios *old) | ||
380 | { | ||
381 | struct rp2_uart_port *up = port_to_up(port); | ||
382 | unsigned long flags; | ||
383 | unsigned int baud, baud_div; | ||
384 | |||
385 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | ||
386 | baud_div = uart_get_divisor(port, baud); | ||
387 | |||
388 | if (tty_termios_baud_rate(new)) | ||
389 | tty_termios_encode_baud_rate(new, baud, baud); | ||
390 | |||
391 | spin_lock_irqsave(&port->lock, flags); | ||
392 | |||
393 | /* ignore all characters if CREAD is not set */ | ||
394 | port->ignore_status_mask = (new->c_cflag & CREAD) ? 0 : RP2_DUMMY_READ; | ||
395 | |||
396 | __rp2_uart_set_termios(up, new->c_cflag, new->c_iflag, baud_div); | ||
397 | uart_update_timeout(port, new->c_cflag, baud); | ||
398 | |||
399 | spin_unlock_irqrestore(&port->lock, flags); | ||
400 | } | ||
401 | |||
402 | static void rp2_rx_chars(struct rp2_uart_port *up) | ||
403 | { | ||
404 | u16 bytes = readw(up->base + RP2_RX_FIFO_COUNT); | ||
405 | struct tty_port *port = &up->port.state->port; | ||
406 | |||
407 | for (; bytes != 0; bytes--) { | ||
408 | u32 byte = readw(up->base + RP2_DATA_BYTE) | RP2_DUMMY_READ; | ||
409 | char ch = byte & 0xff; | ||
410 | |||
411 | if (likely(!(byte & RP2_DATA_BYTE_EXCEPTION_MASK))) { | ||
412 | if (!uart_handle_sysrq_char(&up->port, ch)) | ||
413 | uart_insert_char(&up->port, byte, 0, ch, | ||
414 | TTY_NORMAL); | ||
415 | } else { | ||
416 | char flag = TTY_NORMAL; | ||
417 | |||
418 | if (byte & RP2_DATA_BYTE_BREAK_m) | ||
419 | flag = TTY_BREAK; | ||
420 | else if (byte & RP2_DATA_BYTE_ERR_FRAMING_m) | ||
421 | flag = TTY_FRAME; | ||
422 | else if (byte & RP2_DATA_BYTE_ERR_PARITY_m) | ||
423 | flag = TTY_PARITY; | ||
424 | uart_insert_char(&up->port, byte, | ||
425 | RP2_DATA_BYTE_ERR_OVERRUN_m, ch, flag); | ||
426 | } | ||
427 | up->port.icount.rx++; | ||
428 | } | ||
429 | |||
430 | tty_flip_buffer_push(port); | ||
431 | } | ||
432 | |||
433 | static void rp2_tx_chars(struct rp2_uart_port *up) | ||
434 | { | ||
435 | u16 max_tx = FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT); | ||
436 | struct circ_buf *xmit = &up->port.state->xmit; | ||
437 | |||
438 | if (uart_tx_stopped(&up->port)) { | ||
439 | rp2_uart_stop_tx(&up->port); | ||
440 | return; | ||
441 | } | ||
442 | |||
443 | for (; max_tx != 0; max_tx--) { | ||
444 | if (up->port.x_char) { | ||
445 | writeb(up->port.x_char, up->base + RP2_DATA_BYTE); | ||
446 | up->port.x_char = 0; | ||
447 | up->port.icount.tx++; | ||
448 | continue; | ||
449 | } | ||
450 | if (uart_circ_empty(xmit)) { | ||
451 | rp2_uart_stop_tx(&up->port); | ||
452 | break; | ||
453 | } | ||
454 | writeb(xmit->buf[xmit->tail], up->base + RP2_DATA_BYTE); | ||
455 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
456 | up->port.icount.tx++; | ||
457 | } | ||
458 | |||
459 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
460 | uart_write_wakeup(&up->port); | ||
461 | } | ||
462 | |||
463 | static void rp2_ch_interrupt(struct rp2_uart_port *up) | ||
464 | { | ||
465 | u32 status; | ||
466 | |||
467 | spin_lock(&up->port.lock); | ||
468 | |||
469 | /* | ||
470 | * The IRQ status bits are clear-on-write. Other status bits in | ||
471 | * this register aren't, so it's harmless to write to them. | ||
472 | */ | ||
473 | status = readl(up->base + RP2_CHAN_STAT); | ||
474 | writel(status, up->base + RP2_CHAN_STAT); | ||
475 | |||
476 | if (status & RP2_CHAN_STAT_RXDATA_m) | ||
477 | rp2_rx_chars(up); | ||
478 | if (status & RP2_CHAN_STAT_TXEMPTY_m) | ||
479 | rp2_tx_chars(up); | ||
480 | if (status & RP2_CHAN_STAT_MS_CHANGED_MASK) | ||
481 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | ||
482 | |||
483 | spin_unlock(&up->port.lock); | ||
484 | } | ||
485 | |||
486 | static int rp2_asic_interrupt(struct rp2_card *card, unsigned int asic_id) | ||
487 | { | ||
488 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); | ||
489 | int ch, handled = 0; | ||
490 | unsigned long status = readl(base + RP2_CH_IRQ_STAT) & | ||
491 | ~readl(base + RP2_CH_IRQ_MASK); | ||
492 | |||
493 | for_each_set_bit(ch, &status, PORTS_PER_ASIC) { | ||
494 | rp2_ch_interrupt(&card->ports[ch]); | ||
495 | handled++; | ||
496 | } | ||
497 | return handled; | ||
498 | } | ||
499 | |||
500 | static irqreturn_t rp2_uart_interrupt(int irq, void *dev_id) | ||
501 | { | ||
502 | struct rp2_card *card = dev_id; | ||
503 | int handled; | ||
504 | |||
505 | handled = rp2_asic_interrupt(card, 0); | ||
506 | if (card->n_ports >= PORTS_PER_ASIC) | ||
507 | handled += rp2_asic_interrupt(card, 1); | ||
508 | |||
509 | return handled ? IRQ_HANDLED : IRQ_NONE; | ||
510 | } | ||
511 | |||
512 | static inline void rp2_flush_fifos(struct rp2_uart_port *up) | ||
513 | { | ||
514 | rp2_rmw_set(up, RP2_UART_CTL, | ||
515 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); | ||
516 | readl(up->base + RP2_UART_CTL); | ||
517 | udelay(10); | ||
518 | rp2_rmw_clr(up, RP2_UART_CTL, | ||
519 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); | ||
520 | } | ||
521 | |||
522 | static int rp2_uart_startup(struct uart_port *port) | ||
523 | { | ||
524 | struct rp2_uart_port *up = port_to_up(port); | ||
525 | |||
526 | rp2_flush_fifos(up); | ||
527 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m, RP2_TXRX_CTL_RXIRQ_m); | ||
528 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_RX_TRIG_m, | ||
529 | RP2_TXRX_CTL_RX_TRIG_1); | ||
530 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); | ||
531 | rp2_mask_ch_irq(up, up->idx, 1); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static void rp2_uart_shutdown(struct uart_port *port) | ||
537 | { | ||
538 | struct rp2_uart_port *up = port_to_up(port); | ||
539 | unsigned long flags; | ||
540 | |||
541 | rp2_uart_break_ctl(port, 0); | ||
542 | |||
543 | spin_lock_irqsave(&port->lock, flags); | ||
544 | rp2_mask_ch_irq(up, up->idx, 0); | ||
545 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); | ||
546 | spin_unlock_irqrestore(&port->lock, flags); | ||
547 | } | ||
548 | |||
549 | static const char *rp2_uart_type(struct uart_port *port) | ||
550 | { | ||
551 | return (port->type == PORT_RP2) ? "RocketPort 2 UART" : NULL; | ||
552 | } | ||
553 | |||
554 | static void rp2_uart_release_port(struct uart_port *port) | ||
555 | { | ||
556 | /* Nothing to release ... */ | ||
557 | } | ||
558 | |||
559 | static int rp2_uart_request_port(struct uart_port *port) | ||
560 | { | ||
561 | /* UARTs always present */ | ||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static void rp2_uart_config_port(struct uart_port *port, int flags) | ||
566 | { | ||
567 | if (flags & UART_CONFIG_TYPE) | ||
568 | port->type = PORT_RP2; | ||
569 | } | ||
570 | |||
571 | static int rp2_uart_verify_port(struct uart_port *port, | ||
572 | struct serial_struct *ser) | ||
573 | { | ||
574 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_RP2) | ||
575 | return -EINVAL; | ||
576 | |||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | static const struct uart_ops rp2_uart_ops = { | ||
581 | .tx_empty = rp2_uart_tx_empty, | ||
582 | .set_mctrl = rp2_uart_set_mctrl, | ||
583 | .get_mctrl = rp2_uart_get_mctrl, | ||
584 | .stop_tx = rp2_uart_stop_tx, | ||
585 | .start_tx = rp2_uart_start_tx, | ||
586 | .stop_rx = rp2_uart_stop_rx, | ||
587 | .enable_ms = rp2_uart_enable_ms, | ||
588 | .break_ctl = rp2_uart_break_ctl, | ||
589 | .startup = rp2_uart_startup, | ||
590 | .shutdown = rp2_uart_shutdown, | ||
591 | .set_termios = rp2_uart_set_termios, | ||
592 | .type = rp2_uart_type, | ||
593 | .release_port = rp2_uart_release_port, | ||
594 | .request_port = rp2_uart_request_port, | ||
595 | .config_port = rp2_uart_config_port, | ||
596 | .verify_port = rp2_uart_verify_port, | ||
597 | }; | ||
598 | |||
599 | static void rp2_reset_asic(struct rp2_card *card, unsigned int asic_id) | ||
600 | { | ||
601 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); | ||
602 | u32 clk_cfg; | ||
603 | |||
604 | writew(1, base + RP2_GLOBAL_CMD); | ||
605 | readw(base + RP2_GLOBAL_CMD); | ||
606 | msleep(100); | ||
607 | writel(0, base + RP2_CLK_PRESCALER); | ||
608 | |||
609 | /* TDM clock configuration */ | ||
610 | clk_cfg = readw(base + RP2_ASIC_CFG); | ||
611 | clk_cfg = (clk_cfg & ~BIT(8)) | BIT(9); | ||
612 | writew(clk_cfg, base + RP2_ASIC_CFG); | ||
613 | |||
614 | /* IRQ routing */ | ||
615 | writel(ALL_PORTS_MASK, base + RP2_CH_IRQ_MASK); | ||
616 | writel(RP2_ASIC_IRQ_EN_m, base + RP2_ASIC_IRQ); | ||
617 | } | ||
618 | |||
619 | static void rp2_init_card(struct rp2_card *card) | ||
620 | { | ||
621 | writel(4, card->bar0 + RP2_FPGA_CTL0); | ||
622 | writel(0, card->bar0 + RP2_FPGA_CTL1); | ||
623 | |||
624 | rp2_reset_asic(card, 0); | ||
625 | if (card->n_ports >= PORTS_PER_ASIC) | ||
626 | rp2_reset_asic(card, 1); | ||
627 | |||
628 | writel(RP2_IRQ_MASK_EN_m, card->bar0 + RP2_IRQ_MASK); | ||
629 | } | ||
630 | |||
631 | static void rp2_init_port(struct rp2_uart_port *up, const struct firmware *fw) | ||
632 | { | ||
633 | int i; | ||
634 | |||
635 | writel(RP2_UART_CTL_RESET_CH_m, up->base + RP2_UART_CTL); | ||
636 | readl(up->base + RP2_UART_CTL); | ||
637 | udelay(1); | ||
638 | |||
639 | writel(0, up->base + RP2_TXRX_CTL); | ||
640 | writel(0, up->base + RP2_UART_CTL); | ||
641 | readl(up->base + RP2_UART_CTL); | ||
642 | udelay(1); | ||
643 | |||
644 | rp2_flush_fifos(up); | ||
645 | |||
646 | for (i = 0; i < min_t(int, fw->size, RP2_UCODE_BYTES); i++) | ||
647 | writeb(fw->data[i], up->ucode + i); | ||
648 | |||
649 | __rp2_uart_set_termios(up, CS8 | CREAD | CLOCAL, 0, DEFAULT_BAUD_DIV); | ||
650 | rp2_uart_set_mctrl(&up->port, 0); | ||
651 | |||
652 | writeb(RP2_RX_FIFO_ena, up->ucode + RP2_RX_FIFO); | ||
653 | rp2_rmw(up, RP2_UART_CTL, RP2_UART_CTL_MODE_m, | ||
654 | RP2_UART_CTL_XMIT_EN_m | RP2_UART_CTL_MODE_rs232); | ||
655 | rp2_rmw_set(up, RP2_TXRX_CTL, | ||
656 | RP2_TXRX_CTL_TX_EN_m | RP2_TXRX_CTL_RX_EN_m); | ||
657 | } | ||
658 | |||
659 | static void rp2_remove_ports(struct rp2_card *card) | ||
660 | { | ||
661 | int i; | ||
662 | |||
663 | for (i = 0; i < card->initialized_ports; i++) | ||
664 | uart_remove_one_port(&rp2_uart_driver, &card->ports[i].port); | ||
665 | card->initialized_ports = 0; | ||
666 | } | ||
667 | |||
668 | static void rp2_fw_cb(const struct firmware *fw, void *context) | ||
669 | { | ||
670 | struct rp2_card *card = context; | ||
671 | resource_size_t phys_base; | ||
672 | int i, rc = -ENOENT; | ||
673 | |||
674 | if (!fw) { | ||
675 | dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n", | ||
676 | RP2_FW_NAME); | ||
677 | goto no_fw; | ||
678 | } | ||
679 | |||
680 | phys_base = pci_resource_start(card->pdev, 1); | ||
681 | |||
682 | for (i = 0; i < card->n_ports; i++) { | ||
683 | struct rp2_uart_port *rp = &card->ports[i]; | ||
684 | struct uart_port *p; | ||
685 | int j = (unsigned)i % PORTS_PER_ASIC; | ||
686 | |||
687 | rp->asic_base = card->bar1; | ||
688 | rp->base = card->bar1 + RP2_PORT_BASE + j*RP2_PORT_SPACING; | ||
689 | rp->ucode = card->bar1 + RP2_UCODE_BASE + j*RP2_UCODE_SPACING; | ||
690 | rp->card = card; | ||
691 | rp->idx = j; | ||
692 | |||
693 | p = &rp->port; | ||
694 | p->line = card->minor_start + i; | ||
695 | p->dev = &card->pdev->dev; | ||
696 | p->type = PORT_RP2; | ||
697 | p->iotype = UPIO_MEM32; | ||
698 | p->uartclk = UART_CLOCK; | ||
699 | p->regshift = 2; | ||
700 | p->fifosize = FIFO_SIZE; | ||
701 | p->ops = &rp2_uart_ops; | ||
702 | p->irq = card->pdev->irq; | ||
703 | p->membase = rp->base; | ||
704 | p->mapbase = phys_base + RP2_PORT_BASE + j*RP2_PORT_SPACING; | ||
705 | |||
706 | if (i >= PORTS_PER_ASIC) { | ||
707 | rp->asic_base += RP2_ASIC_SPACING; | ||
708 | rp->base += RP2_ASIC_SPACING; | ||
709 | rp->ucode += RP2_ASIC_SPACING; | ||
710 | p->mapbase += RP2_ASIC_SPACING; | ||
711 | } | ||
712 | |||
713 | rp2_init_port(rp, fw); | ||
714 | rc = uart_add_one_port(&rp2_uart_driver, p); | ||
715 | if (rc) { | ||
716 | dev_err(&card->pdev->dev, | ||
717 | "error registering port %d: %d\n", i, rc); | ||
718 | rp2_remove_ports(card); | ||
719 | break; | ||
720 | } | ||
721 | card->initialized_ports++; | ||
722 | } | ||
723 | |||
724 | release_firmware(fw); | ||
725 | no_fw: | ||
726 | /* | ||
727 | * rp2_fw_cb() is called from a workqueue long after rp2_probe() | ||
728 | * has already returned success. So if something failed here, | ||
729 | * we'll just leave the now-dormant device in place until somebody | ||
730 | * unbinds it. | ||
731 | */ | ||
732 | if (rc) | ||
733 | dev_warn(&card->pdev->dev, "driver initialization failed\n"); | ||
734 | |||
735 | complete(&card->fw_loaded); | ||
736 | } | ||
737 | |||
738 | static int rp2_probe(struct pci_dev *pdev, | ||
739 | const struct pci_device_id *id) | ||
740 | { | ||
741 | struct rp2_card *card; | ||
742 | struct rp2_uart_port *ports; | ||
743 | void __iomem * const *bars; | ||
744 | int rc; | ||
745 | |||
746 | card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL); | ||
747 | if (!card) | ||
748 | return -ENOMEM; | ||
749 | pci_set_drvdata(pdev, card); | ||
750 | spin_lock_init(&card->card_lock); | ||
751 | init_completion(&card->fw_loaded); | ||
752 | |||
753 | rc = pcim_enable_device(pdev); | ||
754 | if (rc) | ||
755 | return rc; | ||
756 | |||
757 | rc = pcim_iomap_regions_request_all(pdev, 0x03, DRV_NAME); | ||
758 | if (rc) | ||
759 | return rc; | ||
760 | |||
761 | bars = pcim_iomap_table(pdev); | ||
762 | card->bar0 = bars[0]; | ||
763 | card->bar1 = bars[1]; | ||
764 | card->pdev = pdev; | ||
765 | |||
766 | rp2_decode_cap(id, &card->n_ports, &card->smpte); | ||
767 | dev_info(&pdev->dev, "found new card with %d ports\n", card->n_ports); | ||
768 | |||
769 | card->minor_start = rp2_alloc_ports(card->n_ports); | ||
770 | if (card->minor_start < 0) { | ||
771 | dev_err(&pdev->dev, | ||
772 | "too many ports (try increasing CONFIG_SERIAL_RP2_NR_UARTS)\n"); | ||
773 | return -EINVAL; | ||
774 | } | ||
775 | |||
776 | rp2_init_card(card); | ||
777 | |||
778 | ports = devm_kzalloc(&pdev->dev, sizeof(*ports) * card->n_ports, | ||
779 | GFP_KERNEL); | ||
780 | if (!ports) | ||
781 | return -ENOMEM; | ||
782 | card->ports = ports; | ||
783 | |||
784 | rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, | ||
785 | IRQF_SHARED, DRV_NAME, card); | ||
786 | if (rc) | ||
787 | return rc; | ||
788 | |||
789 | /* | ||
790 | * Only catastrophic errors (e.g. ENOMEM) are reported here. | ||
791 | * If the FW image is missing, we'll find out in rp2_fw_cb() | ||
792 | * and print an error message. | ||
793 | */ | ||
794 | rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev, | ||
795 | GFP_KERNEL, card, rp2_fw_cb); | ||
796 | if (rc) | ||
797 | return rc; | ||
798 | dev_dbg(&pdev->dev, "waiting for firmware blob...\n"); | ||
799 | |||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | static void rp2_remove(struct pci_dev *pdev) | ||
804 | { | ||
805 | struct rp2_card *card = pci_get_drvdata(pdev); | ||
806 | |||
807 | wait_for_completion(&card->fw_loaded); | ||
808 | rp2_remove_ports(card); | ||
809 | } | ||
810 | |||
811 | static DEFINE_PCI_DEVICE_TABLE(rp2_pci_tbl) = { | ||
812 | |||
813 | /* RocketPort INFINITY cards */ | ||
814 | |||
815 | { RP_ID(0x0040), RP_CAP(8, 0) }, /* INF Octa, RJ45, selectable */ | ||
816 | { RP_ID(0x0041), RP_CAP(32, 0) }, /* INF 32, ext interface */ | ||
817 | { RP_ID(0x0042), RP_CAP(8, 0) }, /* INF Octa, ext interface */ | ||
818 | { RP_ID(0x0043), RP_CAP(16, 0) }, /* INF 16, ext interface */ | ||
819 | { RP_ID(0x0044), RP_CAP(4, 0) }, /* INF Quad, DB, selectable */ | ||
820 | { RP_ID(0x0045), RP_CAP(8, 0) }, /* INF Octa, DB, selectable */ | ||
821 | { RP_ID(0x0046), RP_CAP(4, 0) }, /* INF Quad, ext interface */ | ||
822 | { RP_ID(0x0047), RP_CAP(4, 0) }, /* INF Quad, RJ45 */ | ||
823 | { RP_ID(0x004a), RP_CAP(4, 0) }, /* INF Plus, Quad */ | ||
824 | { RP_ID(0x004b), RP_CAP(8, 0) }, /* INF Plus, Octa */ | ||
825 | { RP_ID(0x004c), RP_CAP(8, 0) }, /* INF III, Octa */ | ||
826 | { RP_ID(0x004d), RP_CAP(4, 0) }, /* INF III, Quad */ | ||
827 | { RP_ID(0x004e), RP_CAP(2, 0) }, /* INF Plus, 2, RS232 */ | ||
828 | { RP_ID(0x004f), RP_CAP(2, 1) }, /* INF Plus, 2, SMPTE */ | ||
829 | { RP_ID(0x0050), RP_CAP(4, 0) }, /* INF Plus, Quad, RJ45 */ | ||
830 | { RP_ID(0x0051), RP_CAP(8, 0) }, /* INF Plus, Octa, RJ45 */ | ||
831 | { RP_ID(0x0052), RP_CAP(8, 1) }, /* INF Octa, SMPTE */ | ||
832 | |||
833 | /* RocketPort EXPRESS cards */ | ||
834 | |||
835 | { RP_ID(0x0060), RP_CAP(8, 0) }, /* EXP Octa, RJ45, selectable */ | ||
836 | { RP_ID(0x0061), RP_CAP(32, 0) }, /* EXP 32, ext interface */ | ||
837 | { RP_ID(0x0062), RP_CAP(8, 0) }, /* EXP Octa, ext interface */ | ||
838 | { RP_ID(0x0063), RP_CAP(16, 0) }, /* EXP 16, ext interface */ | ||
839 | { RP_ID(0x0064), RP_CAP(4, 0) }, /* EXP Quad, DB, selectable */ | ||
840 | { RP_ID(0x0065), RP_CAP(8, 0) }, /* EXP Octa, DB, selectable */ | ||
841 | { RP_ID(0x0066), RP_CAP(4, 0) }, /* EXP Quad, ext interface */ | ||
842 | { RP_ID(0x0067), RP_CAP(4, 0) }, /* EXP Quad, RJ45 */ | ||
843 | { RP_ID(0x0068), RP_CAP(8, 0) }, /* EXP Octa, RJ11 */ | ||
844 | { RP_ID(0x0072), RP_CAP(8, 1) }, /* EXP Octa, SMPTE */ | ||
845 | { } | ||
846 | }; | ||
847 | MODULE_DEVICE_TABLE(pci, rp2_pci_tbl); | ||
848 | |||
849 | static struct pci_driver rp2_pci_driver = { | ||
850 | .name = DRV_NAME, | ||
851 | .id_table = rp2_pci_tbl, | ||
852 | .probe = rp2_probe, | ||
853 | .remove = rp2_remove, | ||
854 | }; | ||
855 | |||
856 | static int __init rp2_uart_init(void) | ||
857 | { | ||
858 | int rc; | ||
859 | |||
860 | rc = uart_register_driver(&rp2_uart_driver); | ||
861 | if (rc) | ||
862 | return rc; | ||
863 | |||
864 | rc = pci_register_driver(&rp2_pci_driver); | ||
865 | if (rc) { | ||
866 | uart_unregister_driver(&rp2_uart_driver); | ||
867 | return rc; | ||
868 | } | ||
869 | |||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | static void __exit rp2_uart_exit(void) | ||
874 | { | ||
875 | pci_unregister_driver(&rp2_pci_driver); | ||
876 | uart_unregister_driver(&rp2_uart_driver); | ||
877 | } | ||
878 | |||
879 | module_init(rp2_uart_init); | ||
880 | module_exit(rp2_uart_exit); | ||
881 | |||
882 | MODULE_DESCRIPTION("Comtrol RocketPort EXPRESS/INFINITY driver"); | ||
883 | MODULE_AUTHOR("Kevin Cernekee <cernekee@gmail.com>"); | ||
884 | MODULE_LICENSE("GPL v2"); | ||
885 | MODULE_FIRMWARE(RP2_FW_NAME); | ||
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 5d4b9b449b4a..af6b3e3ad24d 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c | |||
@@ -188,7 +188,6 @@ static void sa1100_enable_ms(struct uart_port *port) | |||
188 | static void | 188 | static void |
189 | sa1100_rx_chars(struct sa1100_port *sport) | 189 | sa1100_rx_chars(struct sa1100_port *sport) |
190 | { | 190 | { |
191 | struct tty_struct *tty = sport->port.state->port.tty; | ||
192 | unsigned int status, ch, flg; | 191 | unsigned int status, ch, flg; |
193 | 192 | ||
194 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 193 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
@@ -233,7 +232,7 @@ sa1100_rx_chars(struct sa1100_port *sport) | |||
233 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 232 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
234 | UTSR0_TO_SM(UART_GET_UTSR0(sport)); | 233 | UTSR0_TO_SM(UART_GET_UTSR0(sport)); |
235 | } | 234 | } |
236 | tty_flip_buffer_push(tty); | 235 | tty_flip_buffer_push(&sport->port.state->port); |
237 | } | 236 | } |
238 | 237 | ||
239 | static void sa1100_tx_chars(struct sa1100_port *sport) | 238 | static void sa1100_tx_chars(struct sa1100_port *sport) |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index e514b3a4dc57..2769a38d15b6 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | 48 | ||
49 | #include <mach/hardware.h> | 49 | #include <mach/hardware.h> |
50 | #include <mach/map.h> | ||
51 | 50 | ||
52 | #include <plat/regs-serial.h> | 51 | #include <plat/regs-serial.h> |
53 | #include <plat/clock.h> | 52 | #include <plat/clock.h> |
@@ -221,7 +220,6 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
221 | { | 220 | { |
222 | struct s3c24xx_uart_port *ourport = dev_id; | 221 | struct s3c24xx_uart_port *ourport = dev_id; |
223 | struct uart_port *port = &ourport->port; | 222 | struct uart_port *port = &ourport->port; |
224 | struct tty_struct *tty = port->state->port.tty; | ||
225 | unsigned int ufcon, ch, flag, ufstat, uerstat; | 223 | unsigned int ufcon, ch, flag, ufstat, uerstat; |
226 | unsigned long flags; | 224 | unsigned long flags; |
227 | int max_count = 64; | 225 | int max_count = 64; |
@@ -299,7 +297,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
299 | ignore_char: | 297 | ignore_char: |
300 | continue; | 298 | continue; |
301 | } | 299 | } |
302 | tty_flip_buffer_push(tty); | 300 | tty_flip_buffer_push(&port->state->port); |
303 | 301 | ||
304 | out: | 302 | out: |
305 | spin_unlock_irqrestore(&port->lock, flags); | 303 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -1143,8 +1141,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1143 | 1141 | ||
1144 | dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); | 1142 | dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); |
1145 | 1143 | ||
1144 | port->membase = devm_ioremap(port->dev, res->start, resource_size(res)); | ||
1145 | if (!port->membase) { | ||
1146 | dev_err(port->dev, "failed to remap controller address\n"); | ||
1147 | return -EBUSY; | ||
1148 | } | ||
1149 | |||
1146 | port->mapbase = res->start; | 1150 | port->mapbase = res->start; |
1147 | port->membase = S3C_VA_UART + (res->start & 0xfffff); | ||
1148 | ret = platform_get_irq(platdev, 0); | 1151 | ret = platform_get_irq(platdev, 0); |
1149 | if (ret < 0) | 1152 | if (ret < 0) |
1150 | port->irq = 0; | 1153 | port->irq = 0; |
@@ -1724,8 +1727,6 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = { | |||
1724 | {}, | 1727 | {}, |
1725 | }; | 1728 | }; |
1726 | MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); | 1729 | MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); |
1727 | #else | ||
1728 | #define s3c24xx_uart_dt_match NULL | ||
1729 | #endif | 1730 | #endif |
1730 | 1731 | ||
1731 | static struct platform_driver samsung_serial_driver = { | 1732 | static struct platform_driver samsung_serial_driver = { |
@@ -1736,7 +1737,7 @@ static struct platform_driver samsung_serial_driver = { | |||
1736 | .name = "samsung-uart", | 1737 | .name = "samsung-uart", |
1737 | .owner = THIS_MODULE, | 1738 | .owner = THIS_MODULE, |
1738 | .pm = SERIAL_SAMSUNG_PM_OPS, | 1739 | .pm = SERIAL_SAMSUNG_PM_OPS, |
1739 | .of_match_table = s3c24xx_uart_dt_match, | 1740 | .of_match_table = of_match_ptr(s3c24xx_uart_dt_match), |
1740 | }, | 1741 | }, |
1741 | }; | 1742 | }; |
1742 | 1743 | ||
diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index f76b1688c5c8..a7cdec2962dd 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c | |||
@@ -384,7 +384,7 @@ static void sbd_receive_chars(struct sbd_port *sport) | |||
384 | uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); | 384 | uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); |
385 | } | 385 | } |
386 | 386 | ||
387 | tty_flip_buffer_push(uport->state->port.tty); | 387 | tty_flip_buffer_push(&uport->state->port); |
388 | } | 388 | } |
389 | 389 | ||
390 | static void sbd_transmit_chars(struct sbd_port *sport) | 390 | static void sbd_transmit_chars(struct sbd_port *sport) |
diff --git a/drivers/tty/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c index aced1dd923d8..c9735680762d 100644 --- a/drivers/tty/serial/sc26xx.c +++ b/drivers/tty/serial/sc26xx.c | |||
@@ -136,16 +136,17 @@ static void sc26xx_disable_irq(struct uart_port *port, int mask) | |||
136 | WRITE_SC(port, IMR, up->imr); | 136 | WRITE_SC(port, IMR, up->imr); |
137 | } | 137 | } |
138 | 138 | ||
139 | static struct tty_struct *receive_chars(struct uart_port *port) | 139 | static bool receive_chars(struct uart_port *port) |
140 | { | 140 | { |
141 | struct tty_struct *tty = NULL; | 141 | struct tty_port *tport = NULL; |
142 | int limit = 10000; | 142 | int limit = 10000; |
143 | unsigned char ch; | 143 | unsigned char ch; |
144 | char flag; | 144 | char flag; |
145 | u8 status; | 145 | u8 status; |
146 | 146 | ||
147 | /* FIXME what is this trying to achieve? */ | ||
147 | if (port->state != NULL) /* Unopened serial console */ | 148 | if (port->state != NULL) /* Unopened serial console */ |
148 | tty = port->state->port.tty; | 149 | tport = &port->state->port; |
149 | 150 | ||
150 | while (limit-- > 0) { | 151 | while (limit-- > 0) { |
151 | status = READ_SC_PORT(port, SR); | 152 | status = READ_SC_PORT(port, SR); |
@@ -185,9 +186,9 @@ static struct tty_struct *receive_chars(struct uart_port *port) | |||
185 | if (status & port->ignore_status_mask) | 186 | if (status & port->ignore_status_mask) |
186 | continue; | 187 | continue; |
187 | 188 | ||
188 | tty_insert_flip_char(tty, ch, flag); | 189 | tty_insert_flip_char(tport, ch, flag); |
189 | } | 190 | } |
190 | return tty; | 191 | return !!tport; |
191 | } | 192 | } |
192 | 193 | ||
193 | static void transmit_chars(struct uart_port *port) | 194 | static void transmit_chars(struct uart_port *port) |
@@ -217,36 +218,36 @@ static void transmit_chars(struct uart_port *port) | |||
217 | static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) | 218 | static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) |
218 | { | 219 | { |
219 | struct uart_sc26xx_port *up = dev_id; | 220 | struct uart_sc26xx_port *up = dev_id; |
220 | struct tty_struct *tty; | ||
221 | unsigned long flags; | 221 | unsigned long flags; |
222 | bool push; | ||
222 | u8 isr; | 223 | u8 isr; |
223 | 224 | ||
224 | spin_lock_irqsave(&up->port[0].lock, flags); | 225 | spin_lock_irqsave(&up->port[0].lock, flags); |
225 | 226 | ||
226 | tty = NULL; | 227 | push = false; |
227 | isr = READ_SC(&up->port[0], ISR); | 228 | isr = READ_SC(&up->port[0], ISR); |
228 | if (isr & ISR_TXRDYA) | 229 | if (isr & ISR_TXRDYA) |
229 | transmit_chars(&up->port[0]); | 230 | transmit_chars(&up->port[0]); |
230 | if (isr & ISR_RXRDYA) | 231 | if (isr & ISR_RXRDYA) |
231 | tty = receive_chars(&up->port[0]); | 232 | push = receive_chars(&up->port[0]); |
232 | 233 | ||
233 | spin_unlock(&up->port[0].lock); | 234 | spin_unlock(&up->port[0].lock); |
234 | 235 | ||
235 | if (tty) | 236 | if (push) |
236 | tty_flip_buffer_push(tty); | 237 | tty_flip_buffer_push(&up->port[0].state->port); |
237 | 238 | ||
238 | spin_lock(&up->port[1].lock); | 239 | spin_lock(&up->port[1].lock); |
239 | 240 | ||
240 | tty = NULL; | 241 | push = false; |
241 | if (isr & ISR_TXRDYB) | 242 | if (isr & ISR_TXRDYB) |
242 | transmit_chars(&up->port[1]); | 243 | transmit_chars(&up->port[1]); |
243 | if (isr & ISR_RXRDYB) | 244 | if (isr & ISR_RXRDYB) |
244 | tty = receive_chars(&up->port[1]); | 245 | push = receive_chars(&up->port[1]); |
245 | 246 | ||
246 | spin_unlock_irqrestore(&up->port[1].lock, flags); | 247 | spin_unlock_irqrestore(&up->port[1].lock, flags); |
247 | 248 | ||
248 | if (tty) | 249 | if (push) |
249 | tty_flip_buffer_push(tty); | 250 | tty_flip_buffer_push(&up->port[1].state->port); |
250 | 251 | ||
251 | return IRQ_HANDLED; | 252 | return IRQ_HANDLED; |
252 | } | 253 | } |
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index e869eab180be..08dbfb88d42c 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c | |||
@@ -24,8 +24,9 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/tty.h> | 25 | #include <linux/tty.h> |
26 | #include <linux/tty_flip.h> | 26 | #include <linux/tty_flip.h> |
27 | #include <linux/spinlock.h> | ||
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | #include <linux/platform_data/sccnxp.h> | 29 | #include <linux/platform_data/serial-sccnxp.h> |
29 | 30 | ||
30 | #define SCCNXP_NAME "uart-sccnxp" | 31 | #define SCCNXP_NAME "uart-sccnxp" |
31 | #define SCCNXP_MAJOR 204 | 32 | #define SCCNXP_MAJOR 204 |
@@ -107,6 +108,7 @@ enum { | |||
107 | struct sccnxp_port { | 108 | struct sccnxp_port { |
108 | struct uart_driver uart; | 109 | struct uart_driver uart; |
109 | struct uart_port port[SCCNXP_MAX_UARTS]; | 110 | struct uart_port port[SCCNXP_MAX_UARTS]; |
111 | bool opened[SCCNXP_MAX_UARTS]; | ||
110 | 112 | ||
111 | const char *name; | 113 | const char *name; |
112 | int irq; | 114 | int irq; |
@@ -123,7 +125,10 @@ struct sccnxp_port { | |||
123 | struct console console; | 125 | struct console console; |
124 | #endif | 126 | #endif |
125 | 127 | ||
126 | struct mutex sccnxp_mutex; | 128 | spinlock_t lock; |
129 | |||
130 | bool poll; | ||
131 | struct timer_list timer; | ||
127 | 132 | ||
128 | struct sccnxp_pdata pdata; | 133 | struct sccnxp_pdata pdata; |
129 | }; | 134 | }; |
@@ -175,14 +180,12 @@ static int sccnxp_update_best_err(int a, int b, int *besterr) | |||
175 | return 1; | 180 | return 1; |
176 | } | 181 | } |
177 | 182 | ||
178 | struct baud_table { | 183 | static const struct { |
179 | u8 csr; | 184 | u8 csr; |
180 | u8 acr; | 185 | u8 acr; |
181 | u8 mr0; | 186 | u8 mr0; |
182 | int baud; | 187 | int baud; |
183 | }; | 188 | } baud_std[] = { |
184 | |||
185 | const struct baud_table baud_std[] = { | ||
186 | { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, }, | 189 | { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, }, |
187 | { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, }, | 190 | { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, }, |
188 | { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, }, | 191 | { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, }, |
@@ -286,10 +289,6 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
286 | { | 289 | { |
287 | u8 sr; | 290 | u8 sr; |
288 | unsigned int ch, flag; | 291 | unsigned int ch, flag; |
289 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
290 | |||
291 | if (!tty) | ||
292 | return; | ||
293 | 292 | ||
294 | for (;;) { | 293 | for (;;) { |
295 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); | 294 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); |
@@ -305,14 +304,19 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
305 | if (unlikely(sr)) { | 304 | if (unlikely(sr)) { |
306 | if (sr & SR_BRK) { | 305 | if (sr & SR_BRK) { |
307 | port->icount.brk++; | 306 | port->icount.brk++; |
307 | sccnxp_port_write(port, SCCNXP_CR_REG, | ||
308 | CR_CMD_BREAK_RESET); | ||
308 | if (uart_handle_break(port)) | 309 | if (uart_handle_break(port)) |
309 | continue; | 310 | continue; |
310 | } else if (sr & SR_PE) | 311 | } else if (sr & SR_PE) |
311 | port->icount.parity++; | 312 | port->icount.parity++; |
312 | else if (sr & SR_FE) | 313 | else if (sr & SR_FE) |
313 | port->icount.frame++; | 314 | port->icount.frame++; |
314 | else if (sr & SR_OVR) | 315 | else if (sr & SR_OVR) { |
315 | port->icount.overrun++; | 316 | port->icount.overrun++; |
317 | sccnxp_port_write(port, SCCNXP_CR_REG, | ||
318 | CR_CMD_STATUS_RESET); | ||
319 | } | ||
316 | 320 | ||
317 | sr &= port->read_status_mask; | 321 | sr &= port->read_status_mask; |
318 | if (sr & SR_BRK) | 322 | if (sr & SR_BRK) |
@@ -334,9 +338,7 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
334 | uart_insert_char(port, sr, SR_OVR, ch, flag); | 338 | uart_insert_char(port, sr, SR_OVR, ch, flag); |
335 | } | 339 | } |
336 | 340 | ||
337 | tty_flip_buffer_push(tty); | 341 | tty_flip_buffer_push(&port->state->port); |
338 | |||
339 | tty_kref_put(tty); | ||
340 | } | 342 | } |
341 | 343 | ||
342 | static void sccnxp_handle_tx(struct uart_port *port) | 344 | static void sccnxp_handle_tx(struct uart_port *port) |
@@ -378,31 +380,48 @@ static void sccnxp_handle_tx(struct uart_port *port) | |||
378 | uart_write_wakeup(port); | 380 | uart_write_wakeup(port); |
379 | } | 381 | } |
380 | 382 | ||
381 | static irqreturn_t sccnxp_ist(int irq, void *dev_id) | 383 | static void sccnxp_handle_events(struct sccnxp_port *s) |
382 | { | 384 | { |
383 | int i; | 385 | int i; |
384 | u8 isr; | 386 | u8 isr; |
385 | struct sccnxp_port *s = (struct sccnxp_port *)dev_id; | ||
386 | |||
387 | mutex_lock(&s->sccnxp_mutex); | ||
388 | 387 | ||
389 | for (;;) { | 388 | do { |
390 | isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG); | 389 | isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG); |
391 | isr &= s->imr; | 390 | isr &= s->imr; |
392 | if (!isr) | 391 | if (!isr) |
393 | break; | 392 | break; |
394 | 393 | ||
395 | dev_dbg(s->port[0].dev, "IRQ status: 0x%02x\n", isr); | ||
396 | |||
397 | for (i = 0; i < s->uart.nr; i++) { | 394 | for (i = 0; i < s->uart.nr; i++) { |
398 | if (isr & ISR_RXRDY(i)) | 395 | if (s->opened[i] && (isr & ISR_RXRDY(i))) |
399 | sccnxp_handle_rx(&s->port[i]); | 396 | sccnxp_handle_rx(&s->port[i]); |
400 | if (isr & ISR_TXRDY(i)) | 397 | if (s->opened[i] && (isr & ISR_TXRDY(i))) |
401 | sccnxp_handle_tx(&s->port[i]); | 398 | sccnxp_handle_tx(&s->port[i]); |
402 | } | 399 | } |
403 | } | 400 | } while (1); |
401 | } | ||
402 | |||
403 | static void sccnxp_timer(unsigned long data) | ||
404 | { | ||
405 | struct sccnxp_port *s = (struct sccnxp_port *)data; | ||
406 | unsigned long flags; | ||
404 | 407 | ||
405 | mutex_unlock(&s->sccnxp_mutex); | 408 | spin_lock_irqsave(&s->lock, flags); |
409 | sccnxp_handle_events(s); | ||
410 | spin_unlock_irqrestore(&s->lock, flags); | ||
411 | |||
412 | if (!timer_pending(&s->timer)) | ||
413 | mod_timer(&s->timer, jiffies + | ||
414 | usecs_to_jiffies(s->pdata.poll_time_us)); | ||
415 | } | ||
416 | |||
417 | static irqreturn_t sccnxp_ist(int irq, void *dev_id) | ||
418 | { | ||
419 | struct sccnxp_port *s = (struct sccnxp_port *)dev_id; | ||
420 | unsigned long flags; | ||
421 | |||
422 | spin_lock_irqsave(&s->lock, flags); | ||
423 | sccnxp_handle_events(s); | ||
424 | spin_unlock_irqrestore(&s->lock, flags); | ||
406 | 425 | ||
407 | return IRQ_HANDLED; | 426 | return IRQ_HANDLED; |
408 | } | 427 | } |
@@ -410,8 +429,9 @@ static irqreturn_t sccnxp_ist(int irq, void *dev_id) | |||
410 | static void sccnxp_start_tx(struct uart_port *port) | 429 | static void sccnxp_start_tx(struct uart_port *port) |
411 | { | 430 | { |
412 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 431 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
432 | unsigned long flags; | ||
413 | 433 | ||
414 | mutex_lock(&s->sccnxp_mutex); | 434 | spin_lock_irqsave(&s->lock, flags); |
415 | 435 | ||
416 | /* Set direction to output */ | 436 | /* Set direction to output */ |
417 | if (s->flags & SCCNXP_HAVE_IO) | 437 | if (s->flags & SCCNXP_HAVE_IO) |
@@ -419,7 +439,7 @@ static void sccnxp_start_tx(struct uart_port *port) | |||
419 | 439 | ||
420 | sccnxp_enable_irq(port, IMR_TXRDY); | 440 | sccnxp_enable_irq(port, IMR_TXRDY); |
421 | 441 | ||
422 | mutex_unlock(&s->sccnxp_mutex); | 442 | spin_unlock_irqrestore(&s->lock, flags); |
423 | } | 443 | } |
424 | 444 | ||
425 | static void sccnxp_stop_tx(struct uart_port *port) | 445 | static void sccnxp_stop_tx(struct uart_port *port) |
@@ -430,20 +450,22 @@ static void sccnxp_stop_tx(struct uart_port *port) | |||
430 | static void sccnxp_stop_rx(struct uart_port *port) | 450 | static void sccnxp_stop_rx(struct uart_port *port) |
431 | { | 451 | { |
432 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 452 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
453 | unsigned long flags; | ||
433 | 454 | ||
434 | mutex_lock(&s->sccnxp_mutex); | 455 | spin_lock_irqsave(&s->lock, flags); |
435 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE); | 456 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE); |
436 | mutex_unlock(&s->sccnxp_mutex); | 457 | spin_unlock_irqrestore(&s->lock, flags); |
437 | } | 458 | } |
438 | 459 | ||
439 | static unsigned int sccnxp_tx_empty(struct uart_port *port) | 460 | static unsigned int sccnxp_tx_empty(struct uart_port *port) |
440 | { | 461 | { |
441 | u8 val; | 462 | u8 val; |
463 | unsigned long flags; | ||
442 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 464 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
443 | 465 | ||
444 | mutex_lock(&s->sccnxp_mutex); | 466 | spin_lock_irqsave(&s->lock, flags); |
445 | val = sccnxp_port_read(port, SCCNXP_SR_REG); | 467 | val = sccnxp_port_read(port, SCCNXP_SR_REG); |
446 | mutex_unlock(&s->sccnxp_mutex); | 468 | spin_unlock_irqrestore(&s->lock, flags); |
447 | 469 | ||
448 | return (val & SR_TXEMT) ? TIOCSER_TEMT : 0; | 470 | return (val & SR_TXEMT) ? TIOCSER_TEMT : 0; |
449 | } | 471 | } |
@@ -456,28 +478,30 @@ static void sccnxp_enable_ms(struct uart_port *port) | |||
456 | static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl) | 478 | static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl) |
457 | { | 479 | { |
458 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 480 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
481 | unsigned long flags; | ||
459 | 482 | ||
460 | if (!(s->flags & SCCNXP_HAVE_IO)) | 483 | if (!(s->flags & SCCNXP_HAVE_IO)) |
461 | return; | 484 | return; |
462 | 485 | ||
463 | mutex_lock(&s->sccnxp_mutex); | 486 | spin_lock_irqsave(&s->lock, flags); |
464 | 487 | ||
465 | sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR); | 488 | sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR); |
466 | sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS); | 489 | sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS); |
467 | 490 | ||
468 | mutex_unlock(&s->sccnxp_mutex); | 491 | spin_unlock_irqrestore(&s->lock, flags); |
469 | } | 492 | } |
470 | 493 | ||
471 | static unsigned int sccnxp_get_mctrl(struct uart_port *port) | 494 | static unsigned int sccnxp_get_mctrl(struct uart_port *port) |
472 | { | 495 | { |
473 | u8 bitmask, ipr; | 496 | u8 bitmask, ipr; |
497 | unsigned long flags; | ||
474 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 498 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
475 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | 499 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; |
476 | 500 | ||
477 | if (!(s->flags & SCCNXP_HAVE_IO)) | 501 | if (!(s->flags & SCCNXP_HAVE_IO)) |
478 | return mctrl; | 502 | return mctrl; |
479 | 503 | ||
480 | mutex_lock(&s->sccnxp_mutex); | 504 | spin_lock_irqsave(&s->lock, flags); |
481 | 505 | ||
482 | ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG); | 506 | ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG); |
483 | 507 | ||
@@ -506,7 +530,7 @@ static unsigned int sccnxp_get_mctrl(struct uart_port *port) | |||
506 | mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0; | 530 | mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0; |
507 | } | 531 | } |
508 | 532 | ||
509 | mutex_unlock(&s->sccnxp_mutex); | 533 | spin_unlock_irqrestore(&s->lock, flags); |
510 | 534 | ||
511 | return mctrl; | 535 | return mctrl; |
512 | } | 536 | } |
@@ -514,21 +538,23 @@ static unsigned int sccnxp_get_mctrl(struct uart_port *port) | |||
514 | static void sccnxp_break_ctl(struct uart_port *port, int break_state) | 538 | static void sccnxp_break_ctl(struct uart_port *port, int break_state) |
515 | { | 539 | { |
516 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 540 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
541 | unsigned long flags; | ||
517 | 542 | ||
518 | mutex_lock(&s->sccnxp_mutex); | 543 | spin_lock_irqsave(&s->lock, flags); |
519 | sccnxp_port_write(port, SCCNXP_CR_REG, break_state ? | 544 | sccnxp_port_write(port, SCCNXP_CR_REG, break_state ? |
520 | CR_CMD_START_BREAK : CR_CMD_STOP_BREAK); | 545 | CR_CMD_START_BREAK : CR_CMD_STOP_BREAK); |
521 | mutex_unlock(&s->sccnxp_mutex); | 546 | spin_unlock_irqrestore(&s->lock, flags); |
522 | } | 547 | } |
523 | 548 | ||
524 | static void sccnxp_set_termios(struct uart_port *port, | 549 | static void sccnxp_set_termios(struct uart_port *port, |
525 | struct ktermios *termios, struct ktermios *old) | 550 | struct ktermios *termios, struct ktermios *old) |
526 | { | 551 | { |
527 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 552 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
553 | unsigned long flags; | ||
528 | u8 mr1, mr2; | 554 | u8 mr1, mr2; |
529 | int baud; | 555 | int baud; |
530 | 556 | ||
531 | mutex_lock(&s->sccnxp_mutex); | 557 | spin_lock_irqsave(&s->lock, flags); |
532 | 558 | ||
533 | /* Mask termios capabilities we don't support */ | 559 | /* Mask termios capabilities we don't support */ |
534 | termios->c_cflag &= ~CMSPAR; | 560 | termios->c_cflag &= ~CMSPAR; |
@@ -595,20 +621,22 @@ static void sccnxp_set_termios(struct uart_port *port, | |||
595 | /* Update timeout according to new baud rate */ | 621 | /* Update timeout according to new baud rate */ |
596 | uart_update_timeout(port, termios->c_cflag, baud); | 622 | uart_update_timeout(port, termios->c_cflag, baud); |
597 | 623 | ||
624 | /* Report actual baudrate back to core */ | ||
598 | if (tty_termios_baud_rate(termios)) | 625 | if (tty_termios_baud_rate(termios)) |
599 | tty_termios_encode_baud_rate(termios, baud, baud); | 626 | tty_termios_encode_baud_rate(termios, baud, baud); |
600 | 627 | ||
601 | /* Enable RX & TX */ | 628 | /* Enable RX & TX */ |
602 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); | 629 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); |
603 | 630 | ||
604 | mutex_unlock(&s->sccnxp_mutex); | 631 | spin_unlock_irqrestore(&s->lock, flags); |
605 | } | 632 | } |
606 | 633 | ||
607 | static int sccnxp_startup(struct uart_port *port) | 634 | static int sccnxp_startup(struct uart_port *port) |
608 | { | 635 | { |
609 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 636 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
637 | unsigned long flags; | ||
610 | 638 | ||
611 | mutex_lock(&s->sccnxp_mutex); | 639 | spin_lock_irqsave(&s->lock, flags); |
612 | 640 | ||
613 | if (s->flags & SCCNXP_HAVE_IO) { | 641 | if (s->flags & SCCNXP_HAVE_IO) { |
614 | /* Outputs are controlled manually */ | 642 | /* Outputs are controlled manually */ |
@@ -627,7 +655,9 @@ static int sccnxp_startup(struct uart_port *port) | |||
627 | /* Enable RX interrupt */ | 655 | /* Enable RX interrupt */ |
628 | sccnxp_enable_irq(port, IMR_RXRDY); | 656 | sccnxp_enable_irq(port, IMR_RXRDY); |
629 | 657 | ||
630 | mutex_unlock(&s->sccnxp_mutex); | 658 | s->opened[port->line] = 1; |
659 | |||
660 | spin_unlock_irqrestore(&s->lock, flags); | ||
631 | 661 | ||
632 | return 0; | 662 | return 0; |
633 | } | 663 | } |
@@ -635,8 +665,11 @@ static int sccnxp_startup(struct uart_port *port) | |||
635 | static void sccnxp_shutdown(struct uart_port *port) | 665 | static void sccnxp_shutdown(struct uart_port *port) |
636 | { | 666 | { |
637 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 667 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
668 | unsigned long flags; | ||
638 | 669 | ||
639 | mutex_lock(&s->sccnxp_mutex); | 670 | spin_lock_irqsave(&s->lock, flags); |
671 | |||
672 | s->opened[port->line] = 0; | ||
640 | 673 | ||
641 | /* Disable interrupts */ | 674 | /* Disable interrupts */ |
642 | sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY); | 675 | sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY); |
@@ -648,7 +681,7 @@ static void sccnxp_shutdown(struct uart_port *port) | |||
648 | if (s->flags & SCCNXP_HAVE_IO) | 681 | if (s->flags & SCCNXP_HAVE_IO) |
649 | sccnxp_set_bit(port, DIR_OP, 0); | 682 | sccnxp_set_bit(port, DIR_OP, 0); |
650 | 683 | ||
651 | mutex_unlock(&s->sccnxp_mutex); | 684 | spin_unlock_irqrestore(&s->lock, flags); |
652 | } | 685 | } |
653 | 686 | ||
654 | static const char *sccnxp_type(struct uart_port *port) | 687 | static const char *sccnxp_type(struct uart_port *port) |
@@ -722,10 +755,11 @@ static void sccnxp_console_write(struct console *co, const char *c, unsigned n) | |||
722 | { | 755 | { |
723 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; | 756 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; |
724 | struct uart_port *port = &s->port[co->index]; | 757 | struct uart_port *port = &s->port[co->index]; |
758 | unsigned long flags; | ||
725 | 759 | ||
726 | mutex_lock(&s->sccnxp_mutex); | 760 | spin_lock_irqsave(&s->lock, flags); |
727 | uart_console_write(port, c, n, sccnxp_console_putchar); | 761 | uart_console_write(port, c, n, sccnxp_console_putchar); |
728 | mutex_unlock(&s->sccnxp_mutex); | 762 | spin_unlock_irqrestore(&s->lock, flags); |
729 | } | 763 | } |
730 | 764 | ||
731 | static int sccnxp_console_setup(struct console *co, char *options) | 765 | static int sccnxp_console_setup(struct console *co, char *options) |
@@ -764,7 +798,7 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
764 | } | 798 | } |
765 | platform_set_drvdata(pdev, s); | 799 | platform_set_drvdata(pdev, s); |
766 | 800 | ||
767 | mutex_init(&s->sccnxp_mutex); | 801 | spin_lock_init(&s->lock); |
768 | 802 | ||
769 | /* Individual chip settings */ | 803 | /* Individual chip settings */ |
770 | switch (chiptype) { | 804 | switch (chiptype) { |
@@ -861,11 +895,19 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
861 | } else | 895 | } else |
862 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); | 896 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); |
863 | 897 | ||
864 | s->irq = platform_get_irq(pdev, 0); | 898 | if (s->pdata.poll_time_us) { |
865 | if (s->irq <= 0) { | 899 | dev_info(&pdev->dev, "Using poll mode, resolution %u usecs\n", |
866 | dev_err(&pdev->dev, "Missing irq resource data\n"); | 900 | s->pdata.poll_time_us); |
867 | ret = -ENXIO; | 901 | s->poll = 1; |
868 | goto err_out; | 902 | } |
903 | |||
904 | if (!s->poll) { | ||
905 | s->irq = platform_get_irq(pdev, 0); | ||
906 | if (s->irq < 0) { | ||
907 | dev_err(&pdev->dev, "Missing irq resource data\n"); | ||
908 | ret = -ENXIO; | ||
909 | goto err_out; | ||
910 | } | ||
869 | } | 911 | } |
870 | 912 | ||
871 | /* Check input frequency */ | 913 | /* Check input frequency */ |
@@ -929,13 +971,23 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
929 | if (s->pdata.init) | 971 | if (s->pdata.init) |
930 | s->pdata.init(); | 972 | s->pdata.init(); |
931 | 973 | ||
932 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, sccnxp_ist, | 974 | if (!s->poll) { |
933 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 975 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, |
934 | dev_name(&pdev->dev), s); | 976 | sccnxp_ist, |
935 | if (!ret) | 977 | IRQF_TRIGGER_FALLING | |
978 | IRQF_ONESHOT, | ||
979 | dev_name(&pdev->dev), s); | ||
980 | if (!ret) | ||
981 | return 0; | ||
982 | |||
983 | dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq); | ||
984 | } else { | ||
985 | init_timer(&s->timer); | ||
986 | setup_timer(&s->timer, sccnxp_timer, (unsigned long)s); | ||
987 | mod_timer(&s->timer, jiffies + | ||
988 | usecs_to_jiffies(s->pdata.poll_time_us)); | ||
936 | return 0; | 989 | return 0; |
937 | 990 | } | |
938 | dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq); | ||
939 | 991 | ||
940 | err_out: | 992 | err_out: |
941 | platform_set_drvdata(pdev, NULL); | 993 | platform_set_drvdata(pdev, NULL); |
@@ -948,7 +1000,10 @@ static int sccnxp_remove(struct platform_device *pdev) | |||
948 | int i; | 1000 | int i; |
949 | struct sccnxp_port *s = platform_get_drvdata(pdev); | 1001 | struct sccnxp_port *s = platform_get_drvdata(pdev); |
950 | 1002 | ||
951 | devm_free_irq(&pdev->dev, s->irq, s); | 1003 | if (!s->poll) |
1004 | devm_free_irq(&pdev->dev, s->irq, s); | ||
1005 | else | ||
1006 | del_timer_sync(&s->timer); | ||
952 | 1007 | ||
953 | for (i = 0; i < s->uart.nr; i++) | 1008 | for (i = 0; i < s->uart.nr; i++) |
954 | uart_remove_one_port(&s->uart, &s->port[i]); | 1009 | uart_remove_one_port(&s->uart, &s->port[i]); |
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c new file mode 100644 index 000000000000..372de8ade76a --- /dev/null +++ b/drivers/tty/serial/serial-tegra.c | |||
@@ -0,0 +1,1401 @@ | |||
1 | /* | ||
2 | * serial_tegra.c | ||
3 | * | ||
4 | * High-speed serial driver for NVIDIA Tegra SoCs | ||
5 | * | ||
6 | * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved. | ||
7 | * | ||
8 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms and conditions of the GNU General Public License, | ||
12 | * version 2, as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | */ | ||
22 | |||
23 | #include <linux/clk.h> | ||
24 | #include <linux/debugfs.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/dmaengine.h> | ||
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/dmapool.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/irq.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/of.h> | ||
33 | #include <linux/of_device.h> | ||
34 | #include <linux/pagemap.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/serial.h> | ||
37 | #include <linux/serial_8250.h> | ||
38 | #include <linux/serial_core.h> | ||
39 | #include <linux/serial_reg.h> | ||
40 | #include <linux/slab.h> | ||
41 | #include <linux/string.h> | ||
42 | #include <linux/termios.h> | ||
43 | #include <linux/tty.h> | ||
44 | #include <linux/tty_flip.h> | ||
45 | |||
46 | #include <linux/clk/tegra.h> | ||
47 | |||
48 | #define TEGRA_UART_TYPE "TEGRA_UART" | ||
49 | #define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE) | ||
50 | #define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3) | ||
51 | |||
52 | #define TEGRA_UART_RX_DMA_BUFFER_SIZE 4096 | ||
53 | #define TEGRA_UART_LSR_TXFIFO_FULL 0x100 | ||
54 | #define TEGRA_UART_IER_EORD 0x20 | ||
55 | #define TEGRA_UART_MCR_RTS_EN 0x40 | ||
56 | #define TEGRA_UART_MCR_CTS_EN 0x20 | ||
57 | #define TEGRA_UART_LSR_ANY (UART_LSR_OE | UART_LSR_BI | \ | ||
58 | UART_LSR_PE | UART_LSR_FE) | ||
59 | #define TEGRA_UART_IRDA_CSR 0x08 | ||
60 | #define TEGRA_UART_SIR_ENABLED 0x80 | ||
61 | |||
62 | #define TEGRA_UART_TX_PIO 1 | ||
63 | #define TEGRA_UART_TX_DMA 2 | ||
64 | #define TEGRA_UART_MIN_DMA 16 | ||
65 | #define TEGRA_UART_FIFO_SIZE 32 | ||
66 | |||
67 | /* | ||
68 | * Tx fifo trigger level setting in tegra uart is in | ||
69 | * reverse way then conventional uart. | ||
70 | */ | ||
71 | #define TEGRA_UART_TX_TRIG_16B 0x00 | ||
72 | #define TEGRA_UART_TX_TRIG_8B 0x10 | ||
73 | #define TEGRA_UART_TX_TRIG_4B 0x20 | ||
74 | #define TEGRA_UART_TX_TRIG_1B 0x30 | ||
75 | |||
76 | #define TEGRA_UART_MAXIMUM 5 | ||
77 | |||
78 | /* Default UART setting when started: 115200 no parity, stop, 8 data bits */ | ||
79 | #define TEGRA_UART_DEFAULT_BAUD 115200 | ||
80 | #define TEGRA_UART_DEFAULT_LSR UART_LCR_WLEN8 | ||
81 | |||
82 | /* Tx transfer mode */ | ||
83 | #define TEGRA_TX_PIO 1 | ||
84 | #define TEGRA_TX_DMA 2 | ||
85 | |||
86 | /** | ||
87 | * tegra_uart_chip_data: SOC specific data. | ||
88 | * | ||
89 | * @tx_fifo_full_status: Status flag available for checking tx fifo full. | ||
90 | * @allow_txfifo_reset_fifo_mode: allow_tx fifo reset with fifo mode or not. | ||
91 | * Tegra30 does not allow this. | ||
92 | * @support_clk_src_div: Clock source support the clock divider. | ||
93 | */ | ||
94 | struct tegra_uart_chip_data { | ||
95 | bool tx_fifo_full_status; | ||
96 | bool allow_txfifo_reset_fifo_mode; | ||
97 | bool support_clk_src_div; | ||
98 | }; | ||
99 | |||
100 | struct tegra_uart_port { | ||
101 | struct uart_port uport; | ||
102 | const struct tegra_uart_chip_data *cdata; | ||
103 | |||
104 | struct clk *uart_clk; | ||
105 | unsigned int current_baud; | ||
106 | |||
107 | /* Register shadow */ | ||
108 | unsigned long fcr_shadow; | ||
109 | unsigned long mcr_shadow; | ||
110 | unsigned long lcr_shadow; | ||
111 | unsigned long ier_shadow; | ||
112 | bool rts_active; | ||
113 | |||
114 | int tx_in_progress; | ||
115 | unsigned int tx_bytes; | ||
116 | |||
117 | bool enable_modem_interrupt; | ||
118 | |||
119 | bool rx_timeout; | ||
120 | int rx_in_progress; | ||
121 | int symb_bit; | ||
122 | int dma_req_sel; | ||
123 | |||
124 | struct dma_chan *rx_dma_chan; | ||
125 | struct dma_chan *tx_dma_chan; | ||
126 | dma_addr_t rx_dma_buf_phys; | ||
127 | dma_addr_t tx_dma_buf_phys; | ||
128 | unsigned char *rx_dma_buf_virt; | ||
129 | unsigned char *tx_dma_buf_virt; | ||
130 | struct dma_async_tx_descriptor *tx_dma_desc; | ||
131 | struct dma_async_tx_descriptor *rx_dma_desc; | ||
132 | dma_cookie_t tx_cookie; | ||
133 | dma_cookie_t rx_cookie; | ||
134 | int tx_bytes_requested; | ||
135 | int rx_bytes_requested; | ||
136 | }; | ||
137 | |||
138 | static void tegra_uart_start_next_tx(struct tegra_uart_port *tup); | ||
139 | static int tegra_uart_start_rx_dma(struct tegra_uart_port *tup); | ||
140 | |||
141 | static inline unsigned long tegra_uart_read(struct tegra_uart_port *tup, | ||
142 | unsigned long reg) | ||
143 | { | ||
144 | return readl(tup->uport.membase + (reg << tup->uport.regshift)); | ||
145 | } | ||
146 | |||
147 | static inline void tegra_uart_write(struct tegra_uart_port *tup, unsigned val, | ||
148 | unsigned long reg) | ||
149 | { | ||
150 | writel(val, tup->uport.membase + (reg << tup->uport.regshift)); | ||
151 | } | ||
152 | |||
153 | static inline struct tegra_uart_port *to_tegra_uport(struct uart_port *u) | ||
154 | { | ||
155 | return container_of(u, struct tegra_uart_port, uport); | ||
156 | } | ||
157 | |||
158 | static unsigned int tegra_uart_get_mctrl(struct uart_port *u) | ||
159 | { | ||
160 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
161 | |||
162 | /* | ||
163 | * RI - Ring detector is active | ||
164 | * CD/DCD/CAR - Carrier detect is always active. For some reason | ||
165 | * linux has different names for carrier detect. | ||
166 | * DSR - Data Set ready is active as the hardware doesn't support it. | ||
167 | * Don't know if the linux support this yet? | ||
168 | * CTS - Clear to send. Always set to active, as the hardware handles | ||
169 | * CTS automatically. | ||
170 | */ | ||
171 | if (tup->enable_modem_interrupt) | ||
172 | return TIOCM_RI | TIOCM_CD | TIOCM_DSR | TIOCM_CTS; | ||
173 | return TIOCM_CTS; | ||
174 | } | ||
175 | |||
176 | static void set_rts(struct tegra_uart_port *tup, bool active) | ||
177 | { | ||
178 | unsigned long mcr; | ||
179 | |||
180 | mcr = tup->mcr_shadow; | ||
181 | if (active) | ||
182 | mcr |= TEGRA_UART_MCR_RTS_EN; | ||
183 | else | ||
184 | mcr &= ~TEGRA_UART_MCR_RTS_EN; | ||
185 | if (mcr != tup->mcr_shadow) { | ||
186 | tegra_uart_write(tup, mcr, UART_MCR); | ||
187 | tup->mcr_shadow = mcr; | ||
188 | } | ||
189 | return; | ||
190 | } | ||
191 | |||
192 | static void set_dtr(struct tegra_uart_port *tup, bool active) | ||
193 | { | ||
194 | unsigned long mcr; | ||
195 | |||
196 | mcr = tup->mcr_shadow; | ||
197 | if (active) | ||
198 | mcr |= UART_MCR_DTR; | ||
199 | else | ||
200 | mcr &= ~UART_MCR_DTR; | ||
201 | if (mcr != tup->mcr_shadow) { | ||
202 | tegra_uart_write(tup, mcr, UART_MCR); | ||
203 | tup->mcr_shadow = mcr; | ||
204 | } | ||
205 | return; | ||
206 | } | ||
207 | |||
208 | static void tegra_uart_set_mctrl(struct uart_port *u, unsigned int mctrl) | ||
209 | { | ||
210 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
211 | unsigned long mcr; | ||
212 | int dtr_enable; | ||
213 | |||
214 | mcr = tup->mcr_shadow; | ||
215 | tup->rts_active = !!(mctrl & TIOCM_RTS); | ||
216 | set_rts(tup, tup->rts_active); | ||
217 | |||
218 | dtr_enable = !!(mctrl & TIOCM_DTR); | ||
219 | set_dtr(tup, dtr_enable); | ||
220 | return; | ||
221 | } | ||
222 | |||
223 | static void tegra_uart_break_ctl(struct uart_port *u, int break_ctl) | ||
224 | { | ||
225 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
226 | unsigned long lcr; | ||
227 | |||
228 | lcr = tup->lcr_shadow; | ||
229 | if (break_ctl) | ||
230 | lcr |= UART_LCR_SBC; | ||
231 | else | ||
232 | lcr &= ~UART_LCR_SBC; | ||
233 | tegra_uart_write(tup, lcr, UART_LCR); | ||
234 | tup->lcr_shadow = lcr; | ||
235 | } | ||
236 | |||
237 | /* Wait for a symbol-time. */ | ||
238 | static void tegra_uart_wait_sym_time(struct tegra_uart_port *tup, | ||
239 | unsigned int syms) | ||
240 | { | ||
241 | if (tup->current_baud) | ||
242 | udelay(DIV_ROUND_UP(syms * tup->symb_bit * 1000000, | ||
243 | tup->current_baud)); | ||
244 | } | ||
245 | |||
246 | static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits) | ||
247 | { | ||
248 | unsigned long fcr = tup->fcr_shadow; | ||
249 | |||
250 | if (tup->cdata->allow_txfifo_reset_fifo_mode) { | ||
251 | fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
252 | tegra_uart_write(tup, fcr, UART_FCR); | ||
253 | } else { | ||
254 | fcr &= ~UART_FCR_ENABLE_FIFO; | ||
255 | tegra_uart_write(tup, fcr, UART_FCR); | ||
256 | udelay(60); | ||
257 | fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
258 | tegra_uart_write(tup, fcr, UART_FCR); | ||
259 | fcr |= UART_FCR_ENABLE_FIFO; | ||
260 | tegra_uart_write(tup, fcr, UART_FCR); | ||
261 | } | ||
262 | |||
263 | /* Dummy read to ensure the write is posted */ | ||
264 | tegra_uart_read(tup, UART_SCR); | ||
265 | |||
266 | /* Wait for the flush to propagate. */ | ||
267 | tegra_uart_wait_sym_time(tup, 1); | ||
268 | } | ||
269 | |||
270 | static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) | ||
271 | { | ||
272 | unsigned long rate; | ||
273 | unsigned int divisor; | ||
274 | unsigned long lcr; | ||
275 | int ret; | ||
276 | |||
277 | if (tup->current_baud == baud) | ||
278 | return 0; | ||
279 | |||
280 | if (tup->cdata->support_clk_src_div) { | ||
281 | rate = baud * 16; | ||
282 | ret = clk_set_rate(tup->uart_clk, rate); | ||
283 | if (ret < 0) { | ||
284 | dev_err(tup->uport.dev, | ||
285 | "clk_set_rate() failed for rate %lu\n", rate); | ||
286 | return ret; | ||
287 | } | ||
288 | divisor = 1; | ||
289 | } else { | ||
290 | rate = clk_get_rate(tup->uart_clk); | ||
291 | divisor = DIV_ROUND_CLOSEST(rate, baud * 16); | ||
292 | } | ||
293 | |||
294 | lcr = tup->lcr_shadow; | ||
295 | lcr |= UART_LCR_DLAB; | ||
296 | tegra_uart_write(tup, lcr, UART_LCR); | ||
297 | |||
298 | tegra_uart_write(tup, divisor & 0xFF, UART_TX); | ||
299 | tegra_uart_write(tup, ((divisor >> 8) & 0xFF), UART_IER); | ||
300 | |||
301 | lcr &= ~UART_LCR_DLAB; | ||
302 | tegra_uart_write(tup, lcr, UART_LCR); | ||
303 | |||
304 | /* Dummy read to ensure the write is posted */ | ||
305 | tegra_uart_read(tup, UART_SCR); | ||
306 | |||
307 | tup->current_baud = baud; | ||
308 | |||
309 | /* wait two character intervals at new rate */ | ||
310 | tegra_uart_wait_sym_time(tup, 2); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup, | ||
315 | unsigned long lsr) | ||
316 | { | ||
317 | char flag = TTY_NORMAL; | ||
318 | |||
319 | if (unlikely(lsr & TEGRA_UART_LSR_ANY)) { | ||
320 | if (lsr & UART_LSR_OE) { | ||
321 | /* Overrrun error */ | ||
322 | flag |= TTY_OVERRUN; | ||
323 | tup->uport.icount.overrun++; | ||
324 | dev_err(tup->uport.dev, "Got overrun errors\n"); | ||
325 | } else if (lsr & UART_LSR_PE) { | ||
326 | /* Parity error */ | ||
327 | flag |= TTY_PARITY; | ||
328 | tup->uport.icount.parity++; | ||
329 | dev_err(tup->uport.dev, "Got Parity errors\n"); | ||
330 | } else if (lsr & UART_LSR_FE) { | ||
331 | flag |= TTY_FRAME; | ||
332 | tup->uport.icount.frame++; | ||
333 | dev_err(tup->uport.dev, "Got frame errors\n"); | ||
334 | } else if (lsr & UART_LSR_BI) { | ||
335 | dev_err(tup->uport.dev, "Got Break\n"); | ||
336 | tup->uport.icount.brk++; | ||
337 | /* If FIFO read error without any data, reset Rx FIFO */ | ||
338 | if (!(lsr & UART_LSR_DR) && (lsr & UART_LSR_FIFOE)) | ||
339 | tegra_uart_fifo_reset(tup, UART_FCR_CLEAR_RCVR); | ||
340 | } | ||
341 | } | ||
342 | return flag; | ||
343 | } | ||
344 | |||
345 | static int tegra_uart_request_port(struct uart_port *u) | ||
346 | { | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static void tegra_uart_release_port(struct uart_port *u) | ||
351 | { | ||
352 | /* Nothing to do here */ | ||
353 | } | ||
354 | |||
355 | static void tegra_uart_fill_tx_fifo(struct tegra_uart_port *tup, int max_bytes) | ||
356 | { | ||
357 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
358 | int i; | ||
359 | |||
360 | for (i = 0; i < max_bytes; i++) { | ||
361 | BUG_ON(uart_circ_empty(xmit)); | ||
362 | if (tup->cdata->tx_fifo_full_status) { | ||
363 | unsigned long lsr = tegra_uart_read(tup, UART_LSR); | ||
364 | if ((lsr & TEGRA_UART_LSR_TXFIFO_FULL)) | ||
365 | break; | ||
366 | } | ||
367 | tegra_uart_write(tup, xmit->buf[xmit->tail], UART_TX); | ||
368 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
369 | tup->uport.icount.tx++; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | static void tegra_uart_start_pio_tx(struct tegra_uart_port *tup, | ||
374 | unsigned int bytes) | ||
375 | { | ||
376 | if (bytes > TEGRA_UART_MIN_DMA) | ||
377 | bytes = TEGRA_UART_MIN_DMA; | ||
378 | |||
379 | tup->tx_in_progress = TEGRA_UART_TX_PIO; | ||
380 | tup->tx_bytes = bytes; | ||
381 | tup->ier_shadow |= UART_IER_THRI; | ||
382 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
383 | } | ||
384 | |||
385 | static void tegra_uart_tx_dma_complete(void *args) | ||
386 | { | ||
387 | struct tegra_uart_port *tup = args; | ||
388 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
389 | struct dma_tx_state state; | ||
390 | unsigned long flags; | ||
391 | int count; | ||
392 | |||
393 | dmaengine_tx_status(tup->tx_dma_chan, tup->rx_cookie, &state); | ||
394 | count = tup->tx_bytes_requested - state.residue; | ||
395 | async_tx_ack(tup->tx_dma_desc); | ||
396 | spin_lock_irqsave(&tup->uport.lock, flags); | ||
397 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
398 | tup->tx_in_progress = 0; | ||
399 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
400 | uart_write_wakeup(&tup->uport); | ||
401 | tegra_uart_start_next_tx(tup); | ||
402 | spin_unlock_irqrestore(&tup->uport.lock, flags); | ||
403 | } | ||
404 | |||
405 | static int tegra_uart_start_tx_dma(struct tegra_uart_port *tup, | ||
406 | unsigned long count) | ||
407 | { | ||
408 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
409 | dma_addr_t tx_phys_addr; | ||
410 | |||
411 | dma_sync_single_for_device(tup->uport.dev, tup->tx_dma_buf_phys, | ||
412 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
413 | |||
414 | tup->tx_bytes = count & ~(0xF); | ||
415 | tx_phys_addr = tup->tx_dma_buf_phys + xmit->tail; | ||
416 | tup->tx_dma_desc = dmaengine_prep_slave_single(tup->tx_dma_chan, | ||
417 | tx_phys_addr, tup->tx_bytes, DMA_MEM_TO_DEV, | ||
418 | DMA_PREP_INTERRUPT); | ||
419 | if (!tup->tx_dma_desc) { | ||
420 | dev_err(tup->uport.dev, "Not able to get desc for Tx\n"); | ||
421 | return -EIO; | ||
422 | } | ||
423 | |||
424 | tup->tx_dma_desc->callback = tegra_uart_tx_dma_complete; | ||
425 | tup->tx_dma_desc->callback_param = tup; | ||
426 | tup->tx_in_progress = TEGRA_UART_TX_DMA; | ||
427 | tup->tx_bytes_requested = tup->tx_bytes; | ||
428 | tup->tx_cookie = dmaengine_submit(tup->tx_dma_desc); | ||
429 | dma_async_issue_pending(tup->tx_dma_chan); | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static void tegra_uart_start_next_tx(struct tegra_uart_port *tup) | ||
434 | { | ||
435 | unsigned long tail; | ||
436 | unsigned long count; | ||
437 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
438 | |||
439 | tail = (unsigned long)&xmit->buf[xmit->tail]; | ||
440 | count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
441 | if (!count) | ||
442 | return; | ||
443 | |||
444 | if (count < TEGRA_UART_MIN_DMA) | ||
445 | tegra_uart_start_pio_tx(tup, count); | ||
446 | else if (BYTES_TO_ALIGN(tail) > 0) | ||
447 | tegra_uart_start_pio_tx(tup, BYTES_TO_ALIGN(tail)); | ||
448 | else | ||
449 | tegra_uart_start_tx_dma(tup, count); | ||
450 | } | ||
451 | |||
452 | /* Called by serial core driver with u->lock taken. */ | ||
453 | static void tegra_uart_start_tx(struct uart_port *u) | ||
454 | { | ||
455 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
456 | struct circ_buf *xmit = &u->state->xmit; | ||
457 | |||
458 | if (!uart_circ_empty(xmit) && !tup->tx_in_progress) | ||
459 | tegra_uart_start_next_tx(tup); | ||
460 | } | ||
461 | |||
462 | static unsigned int tegra_uart_tx_empty(struct uart_port *u) | ||
463 | { | ||
464 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
465 | unsigned int ret = 0; | ||
466 | unsigned long flags; | ||
467 | |||
468 | spin_lock_irqsave(&u->lock, flags); | ||
469 | if (!tup->tx_in_progress) { | ||
470 | unsigned long lsr = tegra_uart_read(tup, UART_LSR); | ||
471 | if ((lsr & TX_EMPTY_STATUS) == TX_EMPTY_STATUS) | ||
472 | ret = TIOCSER_TEMT; | ||
473 | } | ||
474 | spin_unlock_irqrestore(&u->lock, flags); | ||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | static void tegra_uart_stop_tx(struct uart_port *u) | ||
479 | { | ||
480 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
481 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
482 | struct dma_tx_state state; | ||
483 | int count; | ||
484 | |||
485 | dmaengine_terminate_all(tup->tx_dma_chan); | ||
486 | dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); | ||
487 | count = tup->tx_bytes_requested - state.residue; | ||
488 | async_tx_ack(tup->tx_dma_desc); | ||
489 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
490 | tup->tx_in_progress = 0; | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | static void tegra_uart_handle_tx_pio(struct tegra_uart_port *tup) | ||
495 | { | ||
496 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
497 | |||
498 | tegra_uart_fill_tx_fifo(tup, tup->tx_bytes); | ||
499 | tup->tx_in_progress = 0; | ||
500 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
501 | uart_write_wakeup(&tup->uport); | ||
502 | tegra_uart_start_next_tx(tup); | ||
503 | return; | ||
504 | } | ||
505 | |||
506 | static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, | ||
507 | struct tty_port *tty) | ||
508 | { | ||
509 | do { | ||
510 | char flag = TTY_NORMAL; | ||
511 | unsigned long lsr = 0; | ||
512 | unsigned char ch; | ||
513 | |||
514 | lsr = tegra_uart_read(tup, UART_LSR); | ||
515 | if (!(lsr & UART_LSR_DR)) | ||
516 | break; | ||
517 | |||
518 | flag = tegra_uart_decode_rx_error(tup, lsr); | ||
519 | ch = (unsigned char) tegra_uart_read(tup, UART_RX); | ||
520 | tup->uport.icount.rx++; | ||
521 | |||
522 | if (!uart_handle_sysrq_char(&tup->uport, ch) && tty) | ||
523 | tty_insert_flip_char(tty, ch, flag); | ||
524 | } while (1); | ||
525 | |||
526 | return; | ||
527 | } | ||
528 | |||
529 | static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, | ||
530 | struct tty_port *tty, int count) | ||
531 | { | ||
532 | int copied; | ||
533 | |||
534 | tup->uport.icount.rx += count; | ||
535 | if (!tty) { | ||
536 | dev_err(tup->uport.dev, "No tty port\n"); | ||
537 | return; | ||
538 | } | ||
539 | dma_sync_single_for_cpu(tup->uport.dev, tup->rx_dma_buf_phys, | ||
540 | TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE); | ||
541 | copied = tty_insert_flip_string(tty, | ||
542 | ((unsigned char *)(tup->rx_dma_buf_virt)), count); | ||
543 | if (copied != count) { | ||
544 | WARN_ON(1); | ||
545 | dev_err(tup->uport.dev, "RxData copy to tty layer failed\n"); | ||
546 | } | ||
547 | dma_sync_single_for_device(tup->uport.dev, tup->rx_dma_buf_phys, | ||
548 | TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE); | ||
549 | } | ||
550 | |||
551 | static void tegra_uart_rx_dma_complete(void *args) | ||
552 | { | ||
553 | struct tegra_uart_port *tup = args; | ||
554 | struct uart_port *u = &tup->uport; | ||
555 | int count = tup->rx_bytes_requested; | ||
556 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
557 | struct tty_port *port = &u->state->port; | ||
558 | unsigned long flags; | ||
559 | |||
560 | async_tx_ack(tup->rx_dma_desc); | ||
561 | spin_lock_irqsave(&u->lock, flags); | ||
562 | |||
563 | /* Deactivate flow control to stop sender */ | ||
564 | if (tup->rts_active) | ||
565 | set_rts(tup, false); | ||
566 | |||
567 | /* If we are here, DMA is stopped */ | ||
568 | if (count) | ||
569 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
570 | |||
571 | tegra_uart_handle_rx_pio(tup, port); | ||
572 | if (tty) { | ||
573 | tty_flip_buffer_push(port); | ||
574 | tty_kref_put(tty); | ||
575 | } | ||
576 | tegra_uart_start_rx_dma(tup); | ||
577 | |||
578 | /* Activate flow control to start transfer */ | ||
579 | if (tup->rts_active) | ||
580 | set_rts(tup, true); | ||
581 | |||
582 | spin_unlock_irqrestore(&u->lock, flags); | ||
583 | } | ||
584 | |||
585 | static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) | ||
586 | { | ||
587 | struct dma_tx_state state; | ||
588 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
589 | struct tty_port *port = &tup->uport.state->port; | ||
590 | int count; | ||
591 | |||
592 | /* Deactivate flow control to stop sender */ | ||
593 | if (tup->rts_active) | ||
594 | set_rts(tup, false); | ||
595 | |||
596 | dmaengine_terminate_all(tup->rx_dma_chan); | ||
597 | dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); | ||
598 | count = tup->rx_bytes_requested - state.residue; | ||
599 | |||
600 | /* If we are here, DMA is stopped */ | ||
601 | if (count) | ||
602 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
603 | |||
604 | tegra_uart_handle_rx_pio(tup, port); | ||
605 | if (tty) { | ||
606 | tty_flip_buffer_push(port); | ||
607 | tty_kref_put(tty); | ||
608 | } | ||
609 | tegra_uart_start_rx_dma(tup); | ||
610 | |||
611 | if (tup->rts_active) | ||
612 | set_rts(tup, true); | ||
613 | } | ||
614 | |||
615 | static int tegra_uart_start_rx_dma(struct tegra_uart_port *tup) | ||
616 | { | ||
617 | unsigned int count = TEGRA_UART_RX_DMA_BUFFER_SIZE; | ||
618 | |||
619 | tup->rx_dma_desc = dmaengine_prep_slave_single(tup->rx_dma_chan, | ||
620 | tup->rx_dma_buf_phys, count, DMA_DEV_TO_MEM, | ||
621 | DMA_PREP_INTERRUPT); | ||
622 | if (!tup->rx_dma_desc) { | ||
623 | dev_err(tup->uport.dev, "Not able to get desc for Rx\n"); | ||
624 | return -EIO; | ||
625 | } | ||
626 | |||
627 | tup->rx_dma_desc->callback = tegra_uart_rx_dma_complete; | ||
628 | tup->rx_dma_desc->callback_param = tup; | ||
629 | dma_sync_single_for_device(tup->uport.dev, tup->rx_dma_buf_phys, | ||
630 | count, DMA_TO_DEVICE); | ||
631 | tup->rx_bytes_requested = count; | ||
632 | tup->rx_cookie = dmaengine_submit(tup->rx_dma_desc); | ||
633 | dma_async_issue_pending(tup->rx_dma_chan); | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static void tegra_uart_handle_modem_signal_change(struct uart_port *u) | ||
638 | { | ||
639 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
640 | unsigned long msr; | ||
641 | |||
642 | msr = tegra_uart_read(tup, UART_MSR); | ||
643 | if (!(msr & UART_MSR_ANY_DELTA)) | ||
644 | return; | ||
645 | |||
646 | if (msr & UART_MSR_TERI) | ||
647 | tup->uport.icount.rng++; | ||
648 | if (msr & UART_MSR_DDSR) | ||
649 | tup->uport.icount.dsr++; | ||
650 | /* We may only get DDCD when HW init and reset */ | ||
651 | if (msr & UART_MSR_DDCD) | ||
652 | uart_handle_dcd_change(&tup->uport, msr & UART_MSR_DCD); | ||
653 | /* Will start/stop_tx accordingly */ | ||
654 | if (msr & UART_MSR_DCTS) | ||
655 | uart_handle_cts_change(&tup->uport, msr & UART_MSR_CTS); | ||
656 | return; | ||
657 | } | ||
658 | |||
659 | static irqreturn_t tegra_uart_isr(int irq, void *data) | ||
660 | { | ||
661 | struct tegra_uart_port *tup = data; | ||
662 | struct uart_port *u = &tup->uport; | ||
663 | unsigned long iir; | ||
664 | unsigned long ier; | ||
665 | bool is_rx_int = false; | ||
666 | unsigned long flags; | ||
667 | |||
668 | spin_lock_irqsave(&u->lock, flags); | ||
669 | while (1) { | ||
670 | iir = tegra_uart_read(tup, UART_IIR); | ||
671 | if (iir & UART_IIR_NO_INT) { | ||
672 | if (is_rx_int) { | ||
673 | tegra_uart_handle_rx_dma(tup); | ||
674 | if (tup->rx_in_progress) { | ||
675 | ier = tup->ier_shadow; | ||
676 | ier |= (UART_IER_RLSI | UART_IER_RTOIE | | ||
677 | TEGRA_UART_IER_EORD); | ||
678 | tup->ier_shadow = ier; | ||
679 | tegra_uart_write(tup, ier, UART_IER); | ||
680 | } | ||
681 | } | ||
682 | spin_unlock_irqrestore(&u->lock, flags); | ||
683 | return IRQ_HANDLED; | ||
684 | } | ||
685 | |||
686 | switch ((iir >> 1) & 0x7) { | ||
687 | case 0: /* Modem signal change interrupt */ | ||
688 | tegra_uart_handle_modem_signal_change(u); | ||
689 | break; | ||
690 | |||
691 | case 1: /* Transmit interrupt only triggered when using PIO */ | ||
692 | tup->ier_shadow &= ~UART_IER_THRI; | ||
693 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
694 | tegra_uart_handle_tx_pio(tup); | ||
695 | break; | ||
696 | |||
697 | case 4: /* End of data */ | ||
698 | case 6: /* Rx timeout */ | ||
699 | case 2: /* Receive */ | ||
700 | if (!is_rx_int) { | ||
701 | is_rx_int = true; | ||
702 | /* Disable Rx interrupts */ | ||
703 | ier = tup->ier_shadow; | ||
704 | ier |= UART_IER_RDI; | ||
705 | tegra_uart_write(tup, ier, UART_IER); | ||
706 | ier &= ~(UART_IER_RDI | UART_IER_RLSI | | ||
707 | UART_IER_RTOIE | TEGRA_UART_IER_EORD); | ||
708 | tup->ier_shadow = ier; | ||
709 | tegra_uart_write(tup, ier, UART_IER); | ||
710 | } | ||
711 | break; | ||
712 | |||
713 | case 3: /* Receive error */ | ||
714 | tegra_uart_decode_rx_error(tup, | ||
715 | tegra_uart_read(tup, UART_LSR)); | ||
716 | break; | ||
717 | |||
718 | case 5: /* break nothing to handle */ | ||
719 | case 7: /* break nothing to handle */ | ||
720 | break; | ||
721 | } | ||
722 | } | ||
723 | } | ||
724 | |||
725 | static void tegra_uart_stop_rx(struct uart_port *u) | ||
726 | { | ||
727 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
728 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
729 | struct tty_port *port = &u->state->port; | ||
730 | struct dma_tx_state state; | ||
731 | unsigned long ier; | ||
732 | int count; | ||
733 | |||
734 | if (tup->rts_active) | ||
735 | set_rts(tup, false); | ||
736 | |||
737 | if (!tup->rx_in_progress) | ||
738 | return; | ||
739 | |||
740 | tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ | ||
741 | |||
742 | ier = tup->ier_shadow; | ||
743 | ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | | ||
744 | TEGRA_UART_IER_EORD); | ||
745 | tup->ier_shadow = ier; | ||
746 | tegra_uart_write(tup, ier, UART_IER); | ||
747 | tup->rx_in_progress = 0; | ||
748 | if (tup->rx_dma_chan) { | ||
749 | dmaengine_terminate_all(tup->rx_dma_chan); | ||
750 | dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); | ||
751 | async_tx_ack(tup->rx_dma_desc); | ||
752 | count = tup->rx_bytes_requested - state.residue; | ||
753 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
754 | tegra_uart_handle_rx_pio(tup, port); | ||
755 | } else { | ||
756 | tegra_uart_handle_rx_pio(tup, port); | ||
757 | } | ||
758 | if (tty) { | ||
759 | tty_flip_buffer_push(port); | ||
760 | tty_kref_put(tty); | ||
761 | } | ||
762 | return; | ||
763 | } | ||
764 | |||
765 | static void tegra_uart_hw_deinit(struct tegra_uart_port *tup) | ||
766 | { | ||
767 | unsigned long flags; | ||
768 | unsigned long char_time = DIV_ROUND_UP(10000000, tup->current_baud); | ||
769 | unsigned long fifo_empty_time = tup->uport.fifosize * char_time; | ||
770 | unsigned long wait_time; | ||
771 | unsigned long lsr; | ||
772 | unsigned long msr; | ||
773 | unsigned long mcr; | ||
774 | |||
775 | /* Disable interrupts */ | ||
776 | tegra_uart_write(tup, 0, UART_IER); | ||
777 | |||
778 | lsr = tegra_uart_read(tup, UART_LSR); | ||
779 | if ((lsr & UART_LSR_TEMT) != UART_LSR_TEMT) { | ||
780 | msr = tegra_uart_read(tup, UART_MSR); | ||
781 | mcr = tegra_uart_read(tup, UART_MCR); | ||
782 | if ((mcr & TEGRA_UART_MCR_CTS_EN) && (msr & UART_MSR_CTS)) | ||
783 | dev_err(tup->uport.dev, | ||
784 | "Tx Fifo not empty, CTS disabled, waiting\n"); | ||
785 | |||
786 | /* Wait for Tx fifo to be empty */ | ||
787 | while ((lsr & UART_LSR_TEMT) != UART_LSR_TEMT) { | ||
788 | wait_time = min(fifo_empty_time, 100lu); | ||
789 | udelay(wait_time); | ||
790 | fifo_empty_time -= wait_time; | ||
791 | if (!fifo_empty_time) { | ||
792 | msr = tegra_uart_read(tup, UART_MSR); | ||
793 | mcr = tegra_uart_read(tup, UART_MCR); | ||
794 | if ((mcr & TEGRA_UART_MCR_CTS_EN) && | ||
795 | (msr & UART_MSR_CTS)) | ||
796 | dev_err(tup->uport.dev, | ||
797 | "Slave not ready\n"); | ||
798 | break; | ||
799 | } | ||
800 | lsr = tegra_uart_read(tup, UART_LSR); | ||
801 | } | ||
802 | } | ||
803 | |||
804 | spin_lock_irqsave(&tup->uport.lock, flags); | ||
805 | /* Reset the Rx and Tx FIFOs */ | ||
806 | tegra_uart_fifo_reset(tup, UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); | ||
807 | tup->current_baud = 0; | ||
808 | spin_unlock_irqrestore(&tup->uport.lock, flags); | ||
809 | |||
810 | clk_disable_unprepare(tup->uart_clk); | ||
811 | } | ||
812 | |||
813 | static int tegra_uart_hw_init(struct tegra_uart_port *tup) | ||
814 | { | ||
815 | int ret; | ||
816 | |||
817 | tup->fcr_shadow = 0; | ||
818 | tup->mcr_shadow = 0; | ||
819 | tup->lcr_shadow = 0; | ||
820 | tup->ier_shadow = 0; | ||
821 | tup->current_baud = 0; | ||
822 | |||
823 | clk_prepare_enable(tup->uart_clk); | ||
824 | |||
825 | /* Reset the UART controller to clear all previous status.*/ | ||
826 | tegra_periph_reset_assert(tup->uart_clk); | ||
827 | udelay(10); | ||
828 | tegra_periph_reset_deassert(tup->uart_clk); | ||
829 | |||
830 | tup->rx_in_progress = 0; | ||
831 | tup->tx_in_progress = 0; | ||
832 | |||
833 | /* | ||
834 | * Set the trigger level | ||
835 | * | ||
836 | * For PIO mode: | ||
837 | * | ||
838 | * For receive, this will interrupt the CPU after that many number of | ||
839 | * bytes are received, for the remaining bytes the receive timeout | ||
840 | * interrupt is received. Rx high watermark is set to 4. | ||
841 | * | ||
842 | * For transmit, if the trasnmit interrupt is enabled, this will | ||
843 | * interrupt the CPU when the number of entries in the FIFO reaches the | ||
844 | * low watermark. Tx low watermark is set to 16 bytes. | ||
845 | * | ||
846 | * For DMA mode: | ||
847 | * | ||
848 | * Set the Tx trigger to 16. This should match the DMA burst size that | ||
849 | * programmed in the DMA registers. | ||
850 | */ | ||
851 | tup->fcr_shadow = UART_FCR_ENABLE_FIFO; | ||
852 | tup->fcr_shadow |= UART_FCR_R_TRIG_01; | ||
853 | tup->fcr_shadow |= TEGRA_UART_TX_TRIG_16B; | ||
854 | tegra_uart_write(tup, tup->fcr_shadow, UART_FCR); | ||
855 | |||
856 | /* | ||
857 | * Initialize the UART with default configuration | ||
858 | * (115200, N, 8, 1) so that the receive DMA buffer may be | ||
859 | * enqueued | ||
860 | */ | ||
861 | tup->lcr_shadow = TEGRA_UART_DEFAULT_LSR; | ||
862 | tegra_set_baudrate(tup, TEGRA_UART_DEFAULT_BAUD); | ||
863 | tup->fcr_shadow |= UART_FCR_DMA_SELECT; | ||
864 | tegra_uart_write(tup, tup->fcr_shadow, UART_FCR); | ||
865 | |||
866 | ret = tegra_uart_start_rx_dma(tup); | ||
867 | if (ret < 0) { | ||
868 | dev_err(tup->uport.dev, "Not able to start Rx DMA\n"); | ||
869 | return ret; | ||
870 | } | ||
871 | tup->rx_in_progress = 1; | ||
872 | |||
873 | /* | ||
874 | * Enable IE_RXS for the receive status interrupts like line errros. | ||
875 | * Enable IE_RX_TIMEOUT to get the bytes which cannot be DMA'd. | ||
876 | * | ||
877 | * If using DMA mode, enable EORD instead of receive interrupt which | ||
878 | * will interrupt after the UART is done with the receive instead of | ||
879 | * the interrupt when the FIFO "threshold" is reached. | ||
880 | * | ||
881 | * EORD is different interrupt than RX_TIMEOUT - RX_TIMEOUT occurs when | ||
882 | * the DATA is sitting in the FIFO and couldn't be transferred to the | ||
883 | * DMA as the DMA size alignment(4 bytes) is not met. EORD will be | ||
884 | * triggered when there is a pause of the incomming data stream for 4 | ||
885 | * characters long. | ||
886 | * | ||
887 | * For pauses in the data which is not aligned to 4 bytes, we get | ||
888 | * both the EORD as well as RX_TIMEOUT - SW sees RX_TIMEOUT first | ||
889 | * then the EORD. | ||
890 | */ | ||
891 | tup->ier_shadow = UART_IER_RLSI | UART_IER_RTOIE | TEGRA_UART_IER_EORD; | ||
892 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, | ||
897 | bool dma_to_memory) | ||
898 | { | ||
899 | struct dma_chan *dma_chan; | ||
900 | unsigned char *dma_buf; | ||
901 | dma_addr_t dma_phys; | ||
902 | int ret; | ||
903 | struct dma_slave_config dma_sconfig; | ||
904 | dma_cap_mask_t mask; | ||
905 | |||
906 | dma_cap_zero(mask); | ||
907 | dma_cap_set(DMA_SLAVE, mask); | ||
908 | dma_chan = dma_request_channel(mask, NULL, NULL); | ||
909 | if (!dma_chan) { | ||
910 | dev_err(tup->uport.dev, | ||
911 | "Dma channel is not available, will try later\n"); | ||
912 | return -EPROBE_DEFER; | ||
913 | } | ||
914 | |||
915 | if (dma_to_memory) { | ||
916 | dma_buf = dma_alloc_coherent(tup->uport.dev, | ||
917 | TEGRA_UART_RX_DMA_BUFFER_SIZE, | ||
918 | &dma_phys, GFP_KERNEL); | ||
919 | if (!dma_buf) { | ||
920 | dev_err(tup->uport.dev, | ||
921 | "Not able to allocate the dma buffer\n"); | ||
922 | dma_release_channel(dma_chan); | ||
923 | return -ENOMEM; | ||
924 | } | ||
925 | } else { | ||
926 | dma_phys = dma_map_single(tup->uport.dev, | ||
927 | tup->uport.state->xmit.buf, UART_XMIT_SIZE, | ||
928 | DMA_TO_DEVICE); | ||
929 | dma_buf = tup->uport.state->xmit.buf; | ||
930 | } | ||
931 | |||
932 | dma_sconfig.slave_id = tup->dma_req_sel; | ||
933 | if (dma_to_memory) { | ||
934 | dma_sconfig.src_addr = tup->uport.mapbase; | ||
935 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
936 | dma_sconfig.src_maxburst = 4; | ||
937 | } else { | ||
938 | dma_sconfig.dst_addr = tup->uport.mapbase; | ||
939 | dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
940 | dma_sconfig.dst_maxburst = 16; | ||
941 | } | ||
942 | |||
943 | ret = dmaengine_slave_config(dma_chan, &dma_sconfig); | ||
944 | if (ret < 0) { | ||
945 | dev_err(tup->uport.dev, | ||
946 | "Dma slave config failed, err = %d\n", ret); | ||
947 | goto scrub; | ||
948 | } | ||
949 | |||
950 | if (dma_to_memory) { | ||
951 | tup->rx_dma_chan = dma_chan; | ||
952 | tup->rx_dma_buf_virt = dma_buf; | ||
953 | tup->rx_dma_buf_phys = dma_phys; | ||
954 | } else { | ||
955 | tup->tx_dma_chan = dma_chan; | ||
956 | tup->tx_dma_buf_virt = dma_buf; | ||
957 | tup->tx_dma_buf_phys = dma_phys; | ||
958 | } | ||
959 | return 0; | ||
960 | |||
961 | scrub: | ||
962 | dma_release_channel(dma_chan); | ||
963 | return ret; | ||
964 | } | ||
965 | |||
966 | static void tegra_uart_dma_channel_free(struct tegra_uart_port *tup, | ||
967 | bool dma_to_memory) | ||
968 | { | ||
969 | struct dma_chan *dma_chan; | ||
970 | |||
971 | if (dma_to_memory) { | ||
972 | dma_free_coherent(tup->uport.dev, TEGRA_UART_RX_DMA_BUFFER_SIZE, | ||
973 | tup->rx_dma_buf_virt, tup->rx_dma_buf_phys); | ||
974 | dma_chan = tup->rx_dma_chan; | ||
975 | tup->rx_dma_chan = NULL; | ||
976 | tup->rx_dma_buf_phys = 0; | ||
977 | tup->rx_dma_buf_virt = NULL; | ||
978 | } else { | ||
979 | dma_unmap_single(tup->uport.dev, tup->tx_dma_buf_phys, | ||
980 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
981 | dma_chan = tup->tx_dma_chan; | ||
982 | tup->tx_dma_chan = NULL; | ||
983 | tup->tx_dma_buf_phys = 0; | ||
984 | tup->tx_dma_buf_virt = NULL; | ||
985 | } | ||
986 | dma_release_channel(dma_chan); | ||
987 | } | ||
988 | |||
989 | static int tegra_uart_startup(struct uart_port *u) | ||
990 | { | ||
991 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
992 | int ret; | ||
993 | |||
994 | ret = tegra_uart_dma_channel_allocate(tup, false); | ||
995 | if (ret < 0) { | ||
996 | dev_err(u->dev, "Tx Dma allocation failed, err = %d\n", ret); | ||
997 | return ret; | ||
998 | } | ||
999 | |||
1000 | ret = tegra_uart_dma_channel_allocate(tup, true); | ||
1001 | if (ret < 0) { | ||
1002 | dev_err(u->dev, "Rx Dma allocation failed, err = %d\n", ret); | ||
1003 | goto fail_rx_dma; | ||
1004 | } | ||
1005 | |||
1006 | ret = tegra_uart_hw_init(tup); | ||
1007 | if (ret < 0) { | ||
1008 | dev_err(u->dev, "Uart HW init failed, err = %d\n", ret); | ||
1009 | goto fail_hw_init; | ||
1010 | } | ||
1011 | |||
1012 | ret = request_irq(u->irq, tegra_uart_isr, IRQF_DISABLED, | ||
1013 | dev_name(u->dev), tup); | ||
1014 | if (ret < 0) { | ||
1015 | dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq); | ||
1016 | goto fail_hw_init; | ||
1017 | } | ||
1018 | return 0; | ||
1019 | |||
1020 | fail_hw_init: | ||
1021 | tegra_uart_dma_channel_free(tup, true); | ||
1022 | fail_rx_dma: | ||
1023 | tegra_uart_dma_channel_free(tup, false); | ||
1024 | return ret; | ||
1025 | } | ||
1026 | |||
1027 | static void tegra_uart_shutdown(struct uart_port *u) | ||
1028 | { | ||
1029 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1030 | |||
1031 | tegra_uart_hw_deinit(tup); | ||
1032 | |||
1033 | tup->rx_in_progress = 0; | ||
1034 | tup->tx_in_progress = 0; | ||
1035 | |||
1036 | tegra_uart_dma_channel_free(tup, true); | ||
1037 | tegra_uart_dma_channel_free(tup, false); | ||
1038 | free_irq(u->irq, tup); | ||
1039 | } | ||
1040 | |||
1041 | static void tegra_uart_enable_ms(struct uart_port *u) | ||
1042 | { | ||
1043 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1044 | |||
1045 | if (tup->enable_modem_interrupt) { | ||
1046 | tup->ier_shadow |= UART_IER_MSI; | ||
1047 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | static void tegra_uart_set_termios(struct uart_port *u, | ||
1052 | struct ktermios *termios, struct ktermios *oldtermios) | ||
1053 | { | ||
1054 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1055 | unsigned int baud; | ||
1056 | unsigned long flags; | ||
1057 | unsigned int lcr; | ||
1058 | int symb_bit = 1; | ||
1059 | struct clk *parent_clk = clk_get_parent(tup->uart_clk); | ||
1060 | unsigned long parent_clk_rate = clk_get_rate(parent_clk); | ||
1061 | int max_divider = (tup->cdata->support_clk_src_div) ? 0x7FFF : 0xFFFF; | ||
1062 | |||
1063 | max_divider *= 16; | ||
1064 | spin_lock_irqsave(&u->lock, flags); | ||
1065 | |||
1066 | /* Changing configuration, it is safe to stop any rx now */ | ||
1067 | if (tup->rts_active) | ||
1068 | set_rts(tup, false); | ||
1069 | |||
1070 | /* Clear all interrupts as configuration is going to be change */ | ||
1071 | tegra_uart_write(tup, tup->ier_shadow | UART_IER_RDI, UART_IER); | ||
1072 | tegra_uart_read(tup, UART_IER); | ||
1073 | tegra_uart_write(tup, 0, UART_IER); | ||
1074 | tegra_uart_read(tup, UART_IER); | ||
1075 | |||
1076 | /* Parity */ | ||
1077 | lcr = tup->lcr_shadow; | ||
1078 | lcr &= ~UART_LCR_PARITY; | ||
1079 | |||
1080 | /* CMSPAR isn't supported by this driver */ | ||
1081 | termios->c_cflag &= ~CMSPAR; | ||
1082 | |||
1083 | if ((termios->c_cflag & PARENB) == PARENB) { | ||
1084 | symb_bit++; | ||
1085 | if (termios->c_cflag & PARODD) { | ||
1086 | lcr |= UART_LCR_PARITY; | ||
1087 | lcr &= ~UART_LCR_EPAR; | ||
1088 | lcr &= ~UART_LCR_SPAR; | ||
1089 | } else { | ||
1090 | lcr |= UART_LCR_PARITY; | ||
1091 | lcr |= UART_LCR_EPAR; | ||
1092 | lcr &= ~UART_LCR_SPAR; | ||
1093 | } | ||
1094 | } | ||
1095 | |||
1096 | lcr &= ~UART_LCR_WLEN8; | ||
1097 | switch (termios->c_cflag & CSIZE) { | ||
1098 | case CS5: | ||
1099 | lcr |= UART_LCR_WLEN5; | ||
1100 | symb_bit += 5; | ||
1101 | break; | ||
1102 | case CS6: | ||
1103 | lcr |= UART_LCR_WLEN6; | ||
1104 | symb_bit += 6; | ||
1105 | break; | ||
1106 | case CS7: | ||
1107 | lcr |= UART_LCR_WLEN7; | ||
1108 | symb_bit += 7; | ||
1109 | break; | ||
1110 | default: | ||
1111 | lcr |= UART_LCR_WLEN8; | ||
1112 | symb_bit += 8; | ||
1113 | break; | ||
1114 | } | ||
1115 | |||
1116 | /* Stop bits */ | ||
1117 | if (termios->c_cflag & CSTOPB) { | ||
1118 | lcr |= UART_LCR_STOP; | ||
1119 | symb_bit += 2; | ||
1120 | } else { | ||
1121 | lcr &= ~UART_LCR_STOP; | ||
1122 | symb_bit++; | ||
1123 | } | ||
1124 | |||
1125 | tegra_uart_write(tup, lcr, UART_LCR); | ||
1126 | tup->lcr_shadow = lcr; | ||
1127 | tup->symb_bit = symb_bit; | ||
1128 | |||
1129 | /* Baud rate. */ | ||
1130 | baud = uart_get_baud_rate(u, termios, oldtermios, | ||
1131 | parent_clk_rate/max_divider, | ||
1132 | parent_clk_rate/16); | ||
1133 | spin_unlock_irqrestore(&u->lock, flags); | ||
1134 | tegra_set_baudrate(tup, baud); | ||
1135 | if (tty_termios_baud_rate(termios)) | ||
1136 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
1137 | spin_lock_irqsave(&u->lock, flags); | ||
1138 | |||
1139 | /* Flow control */ | ||
1140 | if (termios->c_cflag & CRTSCTS) { | ||
1141 | tup->mcr_shadow |= TEGRA_UART_MCR_CTS_EN; | ||
1142 | tup->mcr_shadow &= ~TEGRA_UART_MCR_RTS_EN; | ||
1143 | tegra_uart_write(tup, tup->mcr_shadow, UART_MCR); | ||
1144 | /* if top layer has asked to set rts active then do so here */ | ||
1145 | if (tup->rts_active) | ||
1146 | set_rts(tup, true); | ||
1147 | } else { | ||
1148 | tup->mcr_shadow &= ~TEGRA_UART_MCR_CTS_EN; | ||
1149 | tup->mcr_shadow &= ~TEGRA_UART_MCR_RTS_EN; | ||
1150 | tegra_uart_write(tup, tup->mcr_shadow, UART_MCR); | ||
1151 | } | ||
1152 | |||
1153 | /* update the port timeout based on new settings */ | ||
1154 | uart_update_timeout(u, termios->c_cflag, baud); | ||
1155 | |||
1156 | /* Make sure all write has completed */ | ||
1157 | tegra_uart_read(tup, UART_IER); | ||
1158 | |||
1159 | /* Reenable interrupt */ | ||
1160 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
1161 | tegra_uart_read(tup, UART_IER); | ||
1162 | |||
1163 | spin_unlock_irqrestore(&u->lock, flags); | ||
1164 | return; | ||
1165 | } | ||
1166 | |||
1167 | /* | ||
1168 | * Flush any TX data submitted for DMA and PIO. Called when the | ||
1169 | * TX circular buffer is reset. | ||
1170 | */ | ||
1171 | static void tegra_uart_flush_buffer(struct uart_port *u) | ||
1172 | { | ||
1173 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1174 | |||
1175 | tup->tx_bytes = 0; | ||
1176 | if (tup->tx_dma_chan) | ||
1177 | dmaengine_terminate_all(tup->tx_dma_chan); | ||
1178 | return; | ||
1179 | } | ||
1180 | |||
1181 | static const char *tegra_uart_type(struct uart_port *u) | ||
1182 | { | ||
1183 | return TEGRA_UART_TYPE; | ||
1184 | } | ||
1185 | |||
1186 | static struct uart_ops tegra_uart_ops = { | ||
1187 | .tx_empty = tegra_uart_tx_empty, | ||
1188 | .set_mctrl = tegra_uart_set_mctrl, | ||
1189 | .get_mctrl = tegra_uart_get_mctrl, | ||
1190 | .stop_tx = tegra_uart_stop_tx, | ||
1191 | .start_tx = tegra_uart_start_tx, | ||
1192 | .stop_rx = tegra_uart_stop_rx, | ||
1193 | .flush_buffer = tegra_uart_flush_buffer, | ||
1194 | .enable_ms = tegra_uart_enable_ms, | ||
1195 | .break_ctl = tegra_uart_break_ctl, | ||
1196 | .startup = tegra_uart_startup, | ||
1197 | .shutdown = tegra_uart_shutdown, | ||
1198 | .set_termios = tegra_uart_set_termios, | ||
1199 | .type = tegra_uart_type, | ||
1200 | .request_port = tegra_uart_request_port, | ||
1201 | .release_port = tegra_uart_release_port, | ||
1202 | }; | ||
1203 | |||
1204 | static struct uart_driver tegra_uart_driver = { | ||
1205 | .owner = THIS_MODULE, | ||
1206 | .driver_name = "tegra_hsuart", | ||
1207 | .dev_name = "ttyTHS", | ||
1208 | .cons = 0, | ||
1209 | .nr = TEGRA_UART_MAXIMUM, | ||
1210 | }; | ||
1211 | |||
1212 | static int tegra_uart_parse_dt(struct platform_device *pdev, | ||
1213 | struct tegra_uart_port *tup) | ||
1214 | { | ||
1215 | struct device_node *np = pdev->dev.of_node; | ||
1216 | u32 of_dma[2]; | ||
1217 | int port; | ||
1218 | |||
1219 | if (of_property_read_u32_array(np, "nvidia,dma-request-selector", | ||
1220 | of_dma, 2) >= 0) { | ||
1221 | tup->dma_req_sel = of_dma[1]; | ||
1222 | } else { | ||
1223 | dev_err(&pdev->dev, "missing dma requestor in device tree\n"); | ||
1224 | return -EINVAL; | ||
1225 | } | ||
1226 | |||
1227 | port = of_alias_get_id(np, "serial"); | ||
1228 | if (port < 0) { | ||
1229 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port); | ||
1230 | return port; | ||
1231 | } | ||
1232 | tup->uport.line = port; | ||
1233 | |||
1234 | tup->enable_modem_interrupt = of_property_read_bool(np, | ||
1235 | "nvidia,enable-modem-interrupt"); | ||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
1239 | struct tegra_uart_chip_data tegra20_uart_chip_data = { | ||
1240 | .tx_fifo_full_status = false, | ||
1241 | .allow_txfifo_reset_fifo_mode = true, | ||
1242 | .support_clk_src_div = false, | ||
1243 | }; | ||
1244 | |||
1245 | struct tegra_uart_chip_data tegra30_uart_chip_data = { | ||
1246 | .tx_fifo_full_status = true, | ||
1247 | .allow_txfifo_reset_fifo_mode = false, | ||
1248 | .support_clk_src_div = true, | ||
1249 | }; | ||
1250 | |||
1251 | static struct of_device_id tegra_uart_of_match[] = { | ||
1252 | { | ||
1253 | .compatible = "nvidia,tegra30-hsuart", | ||
1254 | .data = &tegra30_uart_chip_data, | ||
1255 | }, { | ||
1256 | .compatible = "nvidia,tegra20-hsuart", | ||
1257 | .data = &tegra20_uart_chip_data, | ||
1258 | }, { | ||
1259 | }, | ||
1260 | }; | ||
1261 | MODULE_DEVICE_TABLE(of, tegra_uart_of_match); | ||
1262 | |||
1263 | static int tegra_uart_probe(struct platform_device *pdev) | ||
1264 | { | ||
1265 | struct tegra_uart_port *tup; | ||
1266 | struct uart_port *u; | ||
1267 | struct resource *resource; | ||
1268 | int ret; | ||
1269 | const struct tegra_uart_chip_data *cdata; | ||
1270 | const struct of_device_id *match; | ||
1271 | |||
1272 | match = of_match_device(tegra_uart_of_match, &pdev->dev); | ||
1273 | if (!match) { | ||
1274 | dev_err(&pdev->dev, "Error: No device match found\n"); | ||
1275 | return -ENODEV; | ||
1276 | } | ||
1277 | cdata = match->data; | ||
1278 | |||
1279 | tup = devm_kzalloc(&pdev->dev, sizeof(*tup), GFP_KERNEL); | ||
1280 | if (!tup) { | ||
1281 | dev_err(&pdev->dev, "Failed to allocate memory for tup\n"); | ||
1282 | return -ENOMEM; | ||
1283 | } | ||
1284 | |||
1285 | ret = tegra_uart_parse_dt(pdev, tup); | ||
1286 | if (ret < 0) | ||
1287 | return ret; | ||
1288 | |||
1289 | u = &tup->uport; | ||
1290 | u->dev = &pdev->dev; | ||
1291 | u->ops = &tegra_uart_ops; | ||
1292 | u->type = PORT_TEGRA; | ||
1293 | u->fifosize = 32; | ||
1294 | tup->cdata = cdata; | ||
1295 | |||
1296 | platform_set_drvdata(pdev, tup); | ||
1297 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1298 | if (!resource) { | ||
1299 | dev_err(&pdev->dev, "No IO memory resource\n"); | ||
1300 | return -ENODEV; | ||
1301 | } | ||
1302 | |||
1303 | u->mapbase = resource->start; | ||
1304 | u->membase = devm_request_and_ioremap(&pdev->dev, resource); | ||
1305 | if (!u->membase) { | ||
1306 | dev_err(&pdev->dev, "memregion/iomap address req failed\n"); | ||
1307 | return -EADDRNOTAVAIL; | ||
1308 | } | ||
1309 | |||
1310 | tup->uart_clk = devm_clk_get(&pdev->dev, NULL); | ||
1311 | if (IS_ERR(tup->uart_clk)) { | ||
1312 | dev_err(&pdev->dev, "Couldn't get the clock\n"); | ||
1313 | return PTR_ERR(tup->uart_clk); | ||
1314 | } | ||
1315 | |||
1316 | u->iotype = UPIO_MEM32; | ||
1317 | u->irq = platform_get_irq(pdev, 0); | ||
1318 | u->regshift = 2; | ||
1319 | ret = uart_add_one_port(&tegra_uart_driver, u); | ||
1320 | if (ret < 0) { | ||
1321 | dev_err(&pdev->dev, "Failed to add uart port, err %d\n", ret); | ||
1322 | return ret; | ||
1323 | } | ||
1324 | return ret; | ||
1325 | } | ||
1326 | |||
1327 | static int tegra_uart_remove(struct platform_device *pdev) | ||
1328 | { | ||
1329 | struct tegra_uart_port *tup = platform_get_drvdata(pdev); | ||
1330 | struct uart_port *u = &tup->uport; | ||
1331 | |||
1332 | uart_remove_one_port(&tegra_uart_driver, u); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | #ifdef CONFIG_PM_SLEEP | ||
1337 | static int tegra_uart_suspend(struct device *dev) | ||
1338 | { | ||
1339 | struct tegra_uart_port *tup = dev_get_drvdata(dev); | ||
1340 | struct uart_port *u = &tup->uport; | ||
1341 | |||
1342 | return uart_suspend_port(&tegra_uart_driver, u); | ||
1343 | } | ||
1344 | |||
1345 | static int tegra_uart_resume(struct device *dev) | ||
1346 | { | ||
1347 | struct tegra_uart_port *tup = dev_get_drvdata(dev); | ||
1348 | struct uart_port *u = &tup->uport; | ||
1349 | |||
1350 | return uart_resume_port(&tegra_uart_driver, u); | ||
1351 | } | ||
1352 | #endif | ||
1353 | |||
1354 | static const struct dev_pm_ops tegra_uart_pm_ops = { | ||
1355 | SET_SYSTEM_SLEEP_PM_OPS(tegra_uart_suspend, tegra_uart_resume) | ||
1356 | }; | ||
1357 | |||
1358 | static struct platform_driver tegra_uart_platform_driver = { | ||
1359 | .probe = tegra_uart_probe, | ||
1360 | .remove = tegra_uart_remove, | ||
1361 | .driver = { | ||
1362 | .name = "serial-tegra", | ||
1363 | .of_match_table = tegra_uart_of_match, | ||
1364 | .pm = &tegra_uart_pm_ops, | ||
1365 | }, | ||
1366 | }; | ||
1367 | |||
1368 | static int __init tegra_uart_init(void) | ||
1369 | { | ||
1370 | int ret; | ||
1371 | |||
1372 | ret = uart_register_driver(&tegra_uart_driver); | ||
1373 | if (ret < 0) { | ||
1374 | pr_err("Could not register %s driver\n", | ||
1375 | tegra_uart_driver.driver_name); | ||
1376 | return ret; | ||
1377 | } | ||
1378 | |||
1379 | ret = platform_driver_register(&tegra_uart_platform_driver); | ||
1380 | if (ret < 0) { | ||
1381 | pr_err("Uart platfrom driver register failed, e = %d\n", ret); | ||
1382 | uart_unregister_driver(&tegra_uart_driver); | ||
1383 | return ret; | ||
1384 | } | ||
1385 | return 0; | ||
1386 | } | ||
1387 | |||
1388 | static void __exit tegra_uart_exit(void) | ||
1389 | { | ||
1390 | pr_info("Unloading tegra uart driver\n"); | ||
1391 | platform_driver_unregister(&tegra_uart_platform_driver); | ||
1392 | uart_unregister_driver(&tegra_uart_driver); | ||
1393 | } | ||
1394 | |||
1395 | module_init(tegra_uart_init); | ||
1396 | module_exit(tegra_uart_exit); | ||
1397 | |||
1398 | MODULE_ALIAS("platform:serial-tegra"); | ||
1399 | MODULE_DESCRIPTION("High speed UART driver for tegra chipset"); | ||
1400 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
1401 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2c7230aaefd4..a400002dfa84 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -59,7 +59,8 @@ static struct lock_class_key port_lock_key; | |||
59 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | 59 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
60 | struct ktermios *old_termios); | 60 | struct ktermios *old_termios); |
61 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); | 61 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); |
62 | static void uart_change_pm(struct uart_state *state, int pm_state); | 62 | static void uart_change_pm(struct uart_state *state, |
63 | enum uart_pm_state pm_state); | ||
63 | 64 | ||
64 | static void uart_port_shutdown(struct tty_port *port); | 65 | static void uart_port_shutdown(struct tty_port *port); |
65 | 66 | ||
@@ -866,9 +867,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
866 | port->closing_wait = closing_wait; | 867 | port->closing_wait = closing_wait; |
867 | if (new_info->xmit_fifo_size) | 868 | if (new_info->xmit_fifo_size) |
868 | uport->fifosize = new_info->xmit_fifo_size; | 869 | uport->fifosize = new_info->xmit_fifo_size; |
869 | if (port->tty) | 870 | port->low_latency = (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; |
870 | port->tty->low_latency = | ||
871 | (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
872 | 871 | ||
873 | check_and_exit: | 872 | check_and_exit: |
874 | retval = 0; | 873 | retval = 0; |
@@ -1308,9 +1307,10 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1308 | } | 1307 | } |
1309 | 1308 | ||
1310 | /* | 1309 | /* |
1311 | * In 2.4.5, calls to this will be serialized via the BKL in | 1310 | * Calls to uart_close() are serialised via the tty_lock in |
1312 | * linux/drivers/char/tty_io.c:tty_release() | 1311 | * drivers/tty/tty_io.c:tty_release() |
1313 | * linux/drivers/char/tty_io.c:do_tty_handup() | 1312 | * drivers/tty/tty_io.c:do_tty_hangup() |
1313 | * This runs from a workqueue and can sleep for a _short_ time only. | ||
1314 | */ | 1314 | */ |
1315 | static void uart_close(struct tty_struct *tty, struct file *filp) | 1315 | static void uart_close(struct tty_struct *tty, struct file *filp) |
1316 | { | 1316 | { |
@@ -1365,7 +1365,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1365 | spin_lock_irqsave(&port->lock, flags); | 1365 | spin_lock_irqsave(&port->lock, flags); |
1366 | } else if (!uart_console(uport)) { | 1366 | } else if (!uart_console(uport)) { |
1367 | spin_unlock_irqrestore(&port->lock, flags); | 1367 | spin_unlock_irqrestore(&port->lock, flags); |
1368 | uart_change_pm(state, 3); | 1368 | uart_change_pm(state, UART_PM_STATE_OFF); |
1369 | spin_lock_irqsave(&port->lock, flags); | 1369 | spin_lock_irqsave(&port->lock, flags); |
1370 | } | 1370 | } |
1371 | 1371 | ||
@@ -1437,10 +1437,9 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | /* | 1439 | /* |
1440 | * This is called with the BKL held in | 1440 | * Calls to uart_hangup() are serialised by the tty_lock in |
1441 | * linux/drivers/char/tty_io.c:do_tty_hangup() | 1441 | * drivers/tty/tty_io.c:do_tty_hangup() |
1442 | * We're called from the eventd thread, so we can sleep for | 1442 | * This runs from a workqueue and can sleep for a _short_ time only. |
1443 | * a _short_ time only. | ||
1444 | */ | 1443 | */ |
1445 | static void uart_hangup(struct tty_struct *tty) | 1444 | static void uart_hangup(struct tty_struct *tty) |
1446 | { | 1445 | { |
@@ -1521,8 +1520,8 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) | |||
1521 | } | 1520 | } |
1522 | 1521 | ||
1523 | /* | 1522 | /* |
1524 | * calls to uart_open are serialised by the BKL in | 1523 | * Calls to uart_open are serialised by the tty_lock in |
1525 | * fs/char_dev.c:chrdev_open() | 1524 | * drivers/tty/tty_io.c:tty_open() |
1526 | * Note that if this fails, then uart_close() _will_ be called. | 1525 | * Note that if this fails, then uart_close() _will_ be called. |
1527 | * | 1526 | * |
1528 | * In time, we want to scrap the "opening nonpresent ports" | 1527 | * In time, we want to scrap the "opening nonpresent ports" |
@@ -1564,7 +1563,8 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1564 | */ | 1563 | */ |
1565 | tty->driver_data = state; | 1564 | tty->driver_data = state; |
1566 | state->uart_port->state = state; | 1565 | state->uart_port->state = state; |
1567 | tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; | 1566 | state->port.low_latency = |
1567 | (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
1568 | tty_port_tty_set(port, tty); | 1568 | tty_port_tty_set(port, tty); |
1569 | 1569 | ||
1570 | /* | 1570 | /* |
@@ -1579,7 +1579,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1579 | * Make sure the device is in D0 state. | 1579 | * Make sure the device is in D0 state. |
1580 | */ | 1580 | */ |
1581 | if (port->count == 1) | 1581 | if (port->count == 1) |
1582 | uart_change_pm(state, 0); | 1582 | uart_change_pm(state, UART_PM_STATE_ON); |
1583 | 1583 | ||
1584 | /* | 1584 | /* |
1585 | * Start up the serial port. | 1585 | * Start up the serial port. |
@@ -1620,7 +1620,7 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1620 | { | 1620 | { |
1621 | struct uart_state *state = drv->state + i; | 1621 | struct uart_state *state = drv->state + i; |
1622 | struct tty_port *port = &state->port; | 1622 | struct tty_port *port = &state->port; |
1623 | int pm_state; | 1623 | enum uart_pm_state pm_state; |
1624 | struct uart_port *uport = state->uart_port; | 1624 | struct uart_port *uport = state->uart_port; |
1625 | char stat_buf[32]; | 1625 | char stat_buf[32]; |
1626 | unsigned int status; | 1626 | unsigned int status; |
@@ -1645,12 +1645,12 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1645 | if (capable(CAP_SYS_ADMIN)) { | 1645 | if (capable(CAP_SYS_ADMIN)) { |
1646 | mutex_lock(&port->mutex); | 1646 | mutex_lock(&port->mutex); |
1647 | pm_state = state->pm_state; | 1647 | pm_state = state->pm_state; |
1648 | if (pm_state) | 1648 | if (pm_state != UART_PM_STATE_ON) |
1649 | uart_change_pm(state, 0); | 1649 | uart_change_pm(state, UART_PM_STATE_ON); |
1650 | spin_lock_irq(&uport->lock); | 1650 | spin_lock_irq(&uport->lock); |
1651 | status = uport->ops->get_mctrl(uport); | 1651 | status = uport->ops->get_mctrl(uport); |
1652 | spin_unlock_irq(&uport->lock); | 1652 | spin_unlock_irq(&uport->lock); |
1653 | if (pm_state) | 1653 | if (pm_state != UART_PM_STATE_ON) |
1654 | uart_change_pm(state, pm_state); | 1654 | uart_change_pm(state, pm_state); |
1655 | mutex_unlock(&port->mutex); | 1655 | mutex_unlock(&port->mutex); |
1656 | 1656 | ||
@@ -1897,7 +1897,8 @@ EXPORT_SYMBOL_GPL(uart_set_options); | |||
1897 | * | 1897 | * |
1898 | * Locking: port->mutex has to be held | 1898 | * Locking: port->mutex has to be held |
1899 | */ | 1899 | */ |
1900 | static void uart_change_pm(struct uart_state *state, int pm_state) | 1900 | static void uart_change_pm(struct uart_state *state, |
1901 | enum uart_pm_state pm_state) | ||
1901 | { | 1902 | { |
1902 | struct uart_port *port = state->uart_port; | 1903 | struct uart_port *port = state->uart_port; |
1903 | 1904 | ||
@@ -1982,7 +1983,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
1982 | console_stop(uport->cons); | 1983 | console_stop(uport->cons); |
1983 | 1984 | ||
1984 | if (console_suspend_enabled || !uart_console(uport)) | 1985 | if (console_suspend_enabled || !uart_console(uport)) |
1985 | uart_change_pm(state, 3); | 1986 | uart_change_pm(state, UART_PM_STATE_OFF); |
1986 | 1987 | ||
1987 | mutex_unlock(&port->mutex); | 1988 | mutex_unlock(&port->mutex); |
1988 | 1989 | ||
@@ -2027,7 +2028,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2027 | termios = port->tty->termios; | 2028 | termios = port->tty->termios; |
2028 | 2029 | ||
2029 | if (console_suspend_enabled) | 2030 | if (console_suspend_enabled) |
2030 | uart_change_pm(state, 0); | 2031 | uart_change_pm(state, UART_PM_STATE_ON); |
2031 | uport->ops->set_termios(uport, &termios, NULL); | 2032 | uport->ops->set_termios(uport, &termios, NULL); |
2032 | if (console_suspend_enabled) | 2033 | if (console_suspend_enabled) |
2033 | console_start(uport->cons); | 2034 | console_start(uport->cons); |
@@ -2037,7 +2038,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2037 | const struct uart_ops *ops = uport->ops; | 2038 | const struct uart_ops *ops = uport->ops; |
2038 | int ret; | 2039 | int ret; |
2039 | 2040 | ||
2040 | uart_change_pm(state, 0); | 2041 | uart_change_pm(state, UART_PM_STATE_ON); |
2041 | spin_lock_irq(&uport->lock); | 2042 | spin_lock_irq(&uport->lock); |
2042 | ops->set_mctrl(uport, 0); | 2043 | ops->set_mctrl(uport, 0); |
2043 | spin_unlock_irq(&uport->lock); | 2044 | spin_unlock_irq(&uport->lock); |
@@ -2137,7 +2138,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
2137 | uart_report_port(drv, port); | 2138 | uart_report_port(drv, port); |
2138 | 2139 | ||
2139 | /* Power up port for set_mctrl() */ | 2140 | /* Power up port for set_mctrl() */ |
2140 | uart_change_pm(state, 0); | 2141 | uart_change_pm(state, UART_PM_STATE_ON); |
2141 | 2142 | ||
2142 | /* | 2143 | /* |
2143 | * Ensure that the modem control lines are de-activated. | 2144 | * Ensure that the modem control lines are de-activated. |
@@ -2161,7 +2162,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
2161 | * console if we have one. | 2162 | * console if we have one. |
2162 | */ | 2163 | */ |
2163 | if (!uart_console(port)) | 2164 | if (!uart_console(port)) |
2164 | uart_change_pm(state, 3); | 2165 | uart_change_pm(state, UART_PM_STATE_OFF); |
2165 | } | 2166 | } |
2166 | } | 2167 | } |
2167 | 2168 | ||
@@ -2588,7 +2589,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2588 | } | 2589 | } |
2589 | 2590 | ||
2590 | state->uart_port = uport; | 2591 | state->uart_port = uport; |
2591 | state->pm_state = -1; | 2592 | state->pm_state = UART_PM_STATE_UNDEFINED; |
2592 | 2593 | ||
2593 | uport->cons = drv->cons; | 2594 | uport->cons = drv->cons; |
2594 | uport->state = state; | 2595 | uport->state = state; |
@@ -2642,6 +2643,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2642 | { | 2643 | { |
2643 | struct uart_state *state = drv->state + uport->line; | 2644 | struct uart_state *state = drv->state + uport->line; |
2644 | struct tty_port *port = &state->port; | 2645 | struct tty_port *port = &state->port; |
2646 | int ret = 0; | ||
2645 | 2647 | ||
2646 | BUG_ON(in_interrupt()); | 2648 | BUG_ON(in_interrupt()); |
2647 | 2649 | ||
@@ -2656,6 +2658,11 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2656 | * succeeding while we shut down the port. | 2658 | * succeeding while we shut down the port. |
2657 | */ | 2659 | */ |
2658 | mutex_lock(&port->mutex); | 2660 | mutex_lock(&port->mutex); |
2661 | if (!state->uart_port) { | ||
2662 | mutex_unlock(&port->mutex); | ||
2663 | ret = -EINVAL; | ||
2664 | goto out; | ||
2665 | } | ||
2659 | uport->flags |= UPF_DEAD; | 2666 | uport->flags |= UPF_DEAD; |
2660 | mutex_unlock(&port->mutex); | 2667 | mutex_unlock(&port->mutex); |
2661 | 2668 | ||
@@ -2679,9 +2686,10 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2679 | uport->type = PORT_UNKNOWN; | 2686 | uport->type = PORT_UNKNOWN; |
2680 | 2687 | ||
2681 | state->uart_port = NULL; | 2688 | state->uart_port = NULL; |
2689 | out: | ||
2682 | mutex_unlock(&port_mutex); | 2690 | mutex_unlock(&port_mutex); |
2683 | 2691 | ||
2684 | return 0; | 2692 | return ret; |
2685 | } | 2693 | } |
2686 | 2694 | ||
2687 | /* | 2695 | /* |
@@ -2715,22 +2723,17 @@ EXPORT_SYMBOL(uart_match_port); | |||
2715 | */ | 2723 | */ |
2716 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | 2724 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) |
2717 | { | 2725 | { |
2718 | struct uart_state *state = uport->state; | 2726 | struct tty_port *port = &uport->state->port; |
2719 | struct tty_port *port = &state->port; | ||
2720 | struct tty_ldisc *ld = NULL; | ||
2721 | struct pps_event_time ts; | ||
2722 | struct tty_struct *tty = port->tty; | 2727 | struct tty_struct *tty = port->tty; |
2728 | struct tty_ldisc *ld = tty ? tty_ldisc_ref(tty) : NULL; | ||
2723 | 2729 | ||
2724 | if (tty) | 2730 | if (ld) { |
2725 | ld = tty_ldisc_ref(tty); | 2731 | if (ld->ops->dcd_change) |
2726 | if (ld && ld->ops->dcd_change) | 2732 | ld->ops->dcd_change(tty, status); |
2727 | pps_get_ts(&ts); | 2733 | tty_ldisc_deref(ld); |
2734 | } | ||
2728 | 2735 | ||
2729 | uport->icount.dcd++; | 2736 | uport->icount.dcd++; |
2730 | #ifdef CONFIG_HARD_PPS | ||
2731 | if ((uport->flags & UPF_HARDPPS_CD) && status) | ||
2732 | hardpps(); | ||
2733 | #endif | ||
2734 | 2737 | ||
2735 | if (port->flags & ASYNC_CHECK_CD) { | 2738 | if (port->flags & ASYNC_CHECK_CD) { |
2736 | if (status) | 2739 | if (status) |
@@ -2738,11 +2741,6 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | |||
2738 | else if (tty) | 2741 | else if (tty) |
2739 | tty_hangup(tty); | 2742 | tty_hangup(tty); |
2740 | } | 2743 | } |
2741 | |||
2742 | if (ld && ld->ops->dcd_change) | ||
2743 | ld->ops->dcd_change(tty, status, &ts); | ||
2744 | if (ld) | ||
2745 | tty_ldisc_deref(ld); | ||
2746 | } | 2744 | } |
2747 | EXPORT_SYMBOL_GPL(uart_handle_dcd_change); | 2745 | EXPORT_SYMBOL_GPL(uart_handle_dcd_change); |
2748 | 2746 | ||
@@ -2790,10 +2788,10 @@ EXPORT_SYMBOL_GPL(uart_handle_cts_change); | |||
2790 | void uart_insert_char(struct uart_port *port, unsigned int status, | 2788 | void uart_insert_char(struct uart_port *port, unsigned int status, |
2791 | unsigned int overrun, unsigned int ch, unsigned int flag) | 2789 | unsigned int overrun, unsigned int ch, unsigned int flag) |
2792 | { | 2790 | { |
2793 | struct tty_struct *tty = port->state->port.tty; | 2791 | struct tty_port *tport = &port->state->port; |
2794 | 2792 | ||
2795 | if ((status & port->ignore_status_mask & ~overrun) == 0) | 2793 | if ((status & port->ignore_status_mask & ~overrun) == 0) |
2796 | if (tty_insert_flip_char(tty, ch, flag) == 0) | 2794 | if (tty_insert_flip_char(tport, ch, flag) == 0) |
2797 | ++port->icount.buf_overrun; | 2795 | ++port->icount.buf_overrun; |
2798 | 2796 | ||
2799 | /* | 2797 | /* |
@@ -2801,7 +2799,7 @@ void uart_insert_char(struct uart_port *port, unsigned int status, | |||
2801 | * it doesn't affect the current character. | 2799 | * it doesn't affect the current character. |
2802 | */ | 2800 | */ |
2803 | if (status & ~port->ignore_status_mask & overrun) | 2801 | if (status & ~port->ignore_status_mask & overrun) |
2804 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN) == 0) | 2802 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN) == 0) |
2805 | ++port->icount.buf_overrun; | 2803 | ++port->icount.buf_overrun; |
2806 | } | 2804 | } |
2807 | EXPORT_SYMBOL_GPL(uart_insert_char); | 2805 | EXPORT_SYMBOL_GPL(uart_insert_char); |
diff --git a/drivers/tty/serial/serial_ks8695.c b/drivers/tty/serial/serial_ks8695.c index 9bd004f9da89..e1caa99e3d3b 100644 --- a/drivers/tty/serial/serial_ks8695.c +++ b/drivers/tty/serial/serial_ks8695.c | |||
@@ -153,7 +153,6 @@ static void ks8695uart_disable_ms(struct uart_port *port) | |||
153 | static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) | 153 | static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) |
154 | { | 154 | { |
155 | struct uart_port *port = dev_id; | 155 | struct uart_port *port = dev_id; |
156 | struct tty_struct *tty = port->state->port.tty; | ||
157 | unsigned int status, ch, lsr, flg, max_count = 256; | 156 | unsigned int status, ch, lsr, flg, max_count = 256; |
158 | 157 | ||
159 | status = UART_GET_LSR(port); /* clears pending LSR interrupts */ | 158 | status = UART_GET_LSR(port); /* clears pending LSR interrupts */ |
@@ -200,7 +199,7 @@ static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) | |||
200 | ignore_char: | 199 | ignore_char: |
201 | status = UART_GET_LSR(port); | 200 | status = UART_GET_LSR(port); |
202 | } | 201 | } |
203 | tty_flip_buffer_push(tty); | 202 | tty_flip_buffer_push(&port->state->port); |
204 | 203 | ||
205 | return IRQ_HANDLED; | 204 | return IRQ_HANDLED; |
206 | } | 205 | } |
diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index b52b21aeb250..fe48a0c2b4ca 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c | |||
@@ -277,7 +277,6 @@ static void serial_txx9_initialize(struct uart_port *port) | |||
277 | static inline void | 277 | static inline void |
278 | receive_chars(struct uart_txx9_port *up, unsigned int *status) | 278 | receive_chars(struct uart_txx9_port *up, unsigned int *status) |
279 | { | 279 | { |
280 | struct tty_struct *tty = up->port.state->port.tty; | ||
281 | unsigned char ch; | 280 | unsigned char ch; |
282 | unsigned int disr = *status; | 281 | unsigned int disr = *status; |
283 | int max_count = 256; | 282 | int max_count = 256; |
@@ -346,7 +345,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status) | |||
346 | disr = sio_in(up, TXX9_SIDISR); | 345 | disr = sio_in(up, TXX9_SIDISR); |
347 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); | 346 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); |
348 | spin_unlock(&up->port.lock); | 347 | spin_unlock(&up->port.lock); |
349 | tty_flip_buffer_push(tty); | 348 | tty_flip_buffer_push(&up->port.state->port); |
350 | spin_lock(&up->port.lock); | 349 | spin_lock(&up->port.lock); |
351 | *status = disr; | 350 | *status = disr; |
352 | } | 351 | } |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 61477567423f..156418619949 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -596,7 +596,7 @@ static void sci_transmit_chars(struct uart_port *port) | |||
596 | static void sci_receive_chars(struct uart_port *port) | 596 | static void sci_receive_chars(struct uart_port *port) |
597 | { | 597 | { |
598 | struct sci_port *sci_port = to_sci_port(port); | 598 | struct sci_port *sci_port = to_sci_port(port); |
599 | struct tty_struct *tty = port->state->port.tty; | 599 | struct tty_port *tport = &port->state->port; |
600 | int i, count, copied = 0; | 600 | int i, count, copied = 0; |
601 | unsigned short status; | 601 | unsigned short status; |
602 | unsigned char flag; | 602 | unsigned char flag; |
@@ -607,7 +607,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
607 | 607 | ||
608 | while (1) { | 608 | while (1) { |
609 | /* Don't copy more bytes than there is room for in the buffer */ | 609 | /* Don't copy more bytes than there is room for in the buffer */ |
610 | count = tty_buffer_request_room(tty, sci_rxfill(port)); | 610 | count = tty_buffer_request_room(tport, sci_rxfill(port)); |
611 | 611 | ||
612 | /* If for any reason we can't copy more data, we're done! */ | 612 | /* If for any reason we can't copy more data, we're done! */ |
613 | if (count == 0) | 613 | if (count == 0) |
@@ -619,7 +619,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
619 | sci_port->break_flag) | 619 | sci_port->break_flag) |
620 | count = 0; | 620 | count = 0; |
621 | else | 621 | else |
622 | tty_insert_flip_char(tty, c, TTY_NORMAL); | 622 | tty_insert_flip_char(tport, c, TTY_NORMAL); |
623 | } else { | 623 | } else { |
624 | for (i = 0; i < count; i++) { | 624 | for (i = 0; i < count; i++) { |
625 | char c = serial_port_in(port, SCxRDR); | 625 | char c = serial_port_in(port, SCxRDR); |
@@ -661,7 +661,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
661 | } else | 661 | } else |
662 | flag = TTY_NORMAL; | 662 | flag = TTY_NORMAL; |
663 | 663 | ||
664 | tty_insert_flip_char(tty, c, flag); | 664 | tty_insert_flip_char(tport, c, flag); |
665 | } | 665 | } |
666 | } | 666 | } |
667 | 667 | ||
@@ -674,7 +674,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
674 | 674 | ||
675 | if (copied) { | 675 | if (copied) { |
676 | /* Tell the rest of the system the news. New characters! */ | 676 | /* Tell the rest of the system the news. New characters! */ |
677 | tty_flip_buffer_push(tty); | 677 | tty_flip_buffer_push(tport); |
678 | } else { | 678 | } else { |
679 | serial_port_in(port, SCxSR); /* dummy read */ | 679 | serial_port_in(port, SCxSR); /* dummy read */ |
680 | serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); | 680 | serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); |
@@ -720,7 +720,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
720 | { | 720 | { |
721 | int copied = 0; | 721 | int copied = 0; |
722 | unsigned short status = serial_port_in(port, SCxSR); | 722 | unsigned short status = serial_port_in(port, SCxSR); |
723 | struct tty_struct *tty = port->state->port.tty; | 723 | struct tty_port *tport = &port->state->port; |
724 | struct sci_port *s = to_sci_port(port); | 724 | struct sci_port *s = to_sci_port(port); |
725 | 725 | ||
726 | /* | 726 | /* |
@@ -731,7 +731,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
731 | port->icount.overrun++; | 731 | port->icount.overrun++; |
732 | 732 | ||
733 | /* overrun error */ | 733 | /* overrun error */ |
734 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) | 734 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) |
735 | copied++; | 735 | copied++; |
736 | 736 | ||
737 | dev_notice(port->dev, "overrun error"); | 737 | dev_notice(port->dev, "overrun error"); |
@@ -755,7 +755,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
755 | 755 | ||
756 | dev_dbg(port->dev, "BREAK detected\n"); | 756 | dev_dbg(port->dev, "BREAK detected\n"); |
757 | 757 | ||
758 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) | 758 | if (tty_insert_flip_char(tport, 0, TTY_BREAK)) |
759 | copied++; | 759 | copied++; |
760 | } | 760 | } |
761 | 761 | ||
@@ -763,7 +763,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
763 | /* frame error */ | 763 | /* frame error */ |
764 | port->icount.frame++; | 764 | port->icount.frame++; |
765 | 765 | ||
766 | if (tty_insert_flip_char(tty, 0, TTY_FRAME)) | 766 | if (tty_insert_flip_char(tport, 0, TTY_FRAME)) |
767 | copied++; | 767 | copied++; |
768 | 768 | ||
769 | dev_notice(port->dev, "frame error\n"); | 769 | dev_notice(port->dev, "frame error\n"); |
@@ -774,21 +774,21 @@ static int sci_handle_errors(struct uart_port *port) | |||
774 | /* parity error */ | 774 | /* parity error */ |
775 | port->icount.parity++; | 775 | port->icount.parity++; |
776 | 776 | ||
777 | if (tty_insert_flip_char(tty, 0, TTY_PARITY)) | 777 | if (tty_insert_flip_char(tport, 0, TTY_PARITY)) |
778 | copied++; | 778 | copied++; |
779 | 779 | ||
780 | dev_notice(port->dev, "parity error"); | 780 | dev_notice(port->dev, "parity error"); |
781 | } | 781 | } |
782 | 782 | ||
783 | if (copied) | 783 | if (copied) |
784 | tty_flip_buffer_push(tty); | 784 | tty_flip_buffer_push(tport); |
785 | 785 | ||
786 | return copied; | 786 | return copied; |
787 | } | 787 | } |
788 | 788 | ||
789 | static int sci_handle_fifo_overrun(struct uart_port *port) | 789 | static int sci_handle_fifo_overrun(struct uart_port *port) |
790 | { | 790 | { |
791 | struct tty_struct *tty = port->state->port.tty; | 791 | struct tty_port *tport = &port->state->port; |
792 | struct sci_port *s = to_sci_port(port); | 792 | struct sci_port *s = to_sci_port(port); |
793 | struct plat_sci_reg *reg; | 793 | struct plat_sci_reg *reg; |
794 | int copied = 0; | 794 | int copied = 0; |
@@ -802,8 +802,8 @@ static int sci_handle_fifo_overrun(struct uart_port *port) | |||
802 | 802 | ||
803 | port->icount.overrun++; | 803 | port->icount.overrun++; |
804 | 804 | ||
805 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 805 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
806 | tty_flip_buffer_push(tty); | 806 | tty_flip_buffer_push(tport); |
807 | 807 | ||
808 | dev_notice(port->dev, "overrun error\n"); | 808 | dev_notice(port->dev, "overrun error\n"); |
809 | copied++; | 809 | copied++; |
@@ -816,7 +816,7 @@ static int sci_handle_breaks(struct uart_port *port) | |||
816 | { | 816 | { |
817 | int copied = 0; | 817 | int copied = 0; |
818 | unsigned short status = serial_port_in(port, SCxSR); | 818 | unsigned short status = serial_port_in(port, SCxSR); |
819 | struct tty_struct *tty = port->state->port.tty; | 819 | struct tty_port *tport = &port->state->port; |
820 | struct sci_port *s = to_sci_port(port); | 820 | struct sci_port *s = to_sci_port(port); |
821 | 821 | ||
822 | if (uart_handle_break(port)) | 822 | if (uart_handle_break(port)) |
@@ -831,14 +831,14 @@ static int sci_handle_breaks(struct uart_port *port) | |||
831 | port->icount.brk++; | 831 | port->icount.brk++; |
832 | 832 | ||
833 | /* Notify of BREAK */ | 833 | /* Notify of BREAK */ |
834 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) | 834 | if (tty_insert_flip_char(tport, 0, TTY_BREAK)) |
835 | copied++; | 835 | copied++; |
836 | 836 | ||
837 | dev_dbg(port->dev, "BREAK detected\n"); | 837 | dev_dbg(port->dev, "BREAK detected\n"); |
838 | } | 838 | } |
839 | 839 | ||
840 | if (copied) | 840 | if (copied) |
841 | tty_flip_buffer_push(tty); | 841 | tty_flip_buffer_push(tport); |
842 | 842 | ||
843 | copied += sci_handle_fifo_overrun(port); | 843 | copied += sci_handle_fifo_overrun(port); |
844 | 844 | ||
@@ -1259,13 +1259,13 @@ static void sci_dma_tx_complete(void *arg) | |||
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | /* Locking: called with port lock held */ | 1261 | /* Locking: called with port lock held */ |
1262 | static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | 1262 | static int sci_dma_rx_push(struct sci_port *s, size_t count) |
1263 | size_t count) | ||
1264 | { | 1263 | { |
1265 | struct uart_port *port = &s->port; | 1264 | struct uart_port *port = &s->port; |
1265 | struct tty_port *tport = &port->state->port; | ||
1266 | int i, active, room; | 1266 | int i, active, room; |
1267 | 1267 | ||
1268 | room = tty_buffer_request_room(tty, count); | 1268 | room = tty_buffer_request_room(tport, count); |
1269 | 1269 | ||
1270 | if (s->active_rx == s->cookie_rx[0]) { | 1270 | if (s->active_rx == s->cookie_rx[0]) { |
1271 | active = 0; | 1271 | active = 0; |
@@ -1283,7 +1283,7 @@ static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | |||
1283 | return room; | 1283 | return room; |
1284 | 1284 | ||
1285 | for (i = 0; i < room; i++) | 1285 | for (i = 0; i < room; i++) |
1286 | tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i], | 1286 | tty_insert_flip_char(tport, ((u8 *)sg_virt(&s->sg_rx[active]))[i], |
1287 | TTY_NORMAL); | 1287 | TTY_NORMAL); |
1288 | 1288 | ||
1289 | port->icount.rx += room; | 1289 | port->icount.rx += room; |
@@ -1295,7 +1295,6 @@ static void sci_dma_rx_complete(void *arg) | |||
1295 | { | 1295 | { |
1296 | struct sci_port *s = arg; | 1296 | struct sci_port *s = arg; |
1297 | struct uart_port *port = &s->port; | 1297 | struct uart_port *port = &s->port; |
1298 | struct tty_struct *tty = port->state->port.tty; | ||
1299 | unsigned long flags; | 1298 | unsigned long flags; |
1300 | int count; | 1299 | int count; |
1301 | 1300 | ||
@@ -1303,14 +1302,14 @@ static void sci_dma_rx_complete(void *arg) | |||
1303 | 1302 | ||
1304 | spin_lock_irqsave(&port->lock, flags); | 1303 | spin_lock_irqsave(&port->lock, flags); |
1305 | 1304 | ||
1306 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); | 1305 | count = sci_dma_rx_push(s, s->buf_len_rx); |
1307 | 1306 | ||
1308 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); | 1307 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); |
1309 | 1308 | ||
1310 | spin_unlock_irqrestore(&port->lock, flags); | 1309 | spin_unlock_irqrestore(&port->lock, flags); |
1311 | 1310 | ||
1312 | if (count) | 1311 | if (count) |
1313 | tty_flip_buffer_push(tty); | 1312 | tty_flip_buffer_push(&port->state->port); |
1314 | 1313 | ||
1315 | schedule_work(&s->work_rx); | 1314 | schedule_work(&s->work_rx); |
1316 | } | 1315 | } |
@@ -1404,7 +1403,6 @@ static void work_fn_rx(struct work_struct *work) | |||
1404 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != | 1403 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != |
1405 | DMA_SUCCESS) { | 1404 | DMA_SUCCESS) { |
1406 | /* Handle incomplete DMA receive */ | 1405 | /* Handle incomplete DMA receive */ |
1407 | struct tty_struct *tty = port->state->port.tty; | ||
1408 | struct dma_chan *chan = s->chan_rx; | 1406 | struct dma_chan *chan = s->chan_rx; |
1409 | struct shdma_desc *sh_desc = container_of(desc, | 1407 | struct shdma_desc *sh_desc = container_of(desc, |
1410 | struct shdma_desc, async_tx); | 1408 | struct shdma_desc, async_tx); |
@@ -1416,11 +1414,11 @@ static void work_fn_rx(struct work_struct *work) | |||
1416 | sh_desc->partial, sh_desc->cookie); | 1414 | sh_desc->partial, sh_desc->cookie); |
1417 | 1415 | ||
1418 | spin_lock_irqsave(&port->lock, flags); | 1416 | spin_lock_irqsave(&port->lock, flags); |
1419 | count = sci_dma_rx_push(s, tty, sh_desc->partial); | 1417 | count = sci_dma_rx_push(s, sh_desc->partial); |
1420 | spin_unlock_irqrestore(&port->lock, flags); | 1418 | spin_unlock_irqrestore(&port->lock, flags); |
1421 | 1419 | ||
1422 | if (count) | 1420 | if (count) |
1423 | tty_flip_buffer_push(tty); | 1421 | tty_flip_buffer_push(&port->state->port); |
1424 | 1422 | ||
1425 | sci_submit_rx(s); | 1423 | sci_submit_rx(s); |
1426 | 1424 | ||
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 5da5cb962769..6bbfe9934a4d 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -75,6 +75,20 @@ static struct sirfsoc_uart_port sirfsoc_uart_ports[SIRFSOC_UART_NR] = { | |||
75 | .line = 2, | 75 | .line = 2, |
76 | }, | 76 | }, |
77 | }, | 77 | }, |
78 | [3] = { | ||
79 | .port = { | ||
80 | .iotype = UPIO_MEM, | ||
81 | .flags = UPF_BOOT_AUTOCONF, | ||
82 | .line = 3, | ||
83 | }, | ||
84 | }, | ||
85 | [4] = { | ||
86 | .port = { | ||
87 | .iotype = UPIO_MEM, | ||
88 | .flags = UPF_BOOT_AUTOCONF, | ||
89 | .line = 4, | ||
90 | }, | ||
91 | }, | ||
78 | }; | 92 | }; |
79 | 93 | ||
80 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) | 94 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) |
@@ -192,11 +206,6 @@ static unsigned int | |||
192 | sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | 206 | sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) |
193 | { | 207 | { |
194 | unsigned int ch, rx_count = 0; | 208 | unsigned int ch, rx_count = 0; |
195 | struct tty_struct *tty; | ||
196 | |||
197 | tty = tty_port_tty_get(&port->state->port); | ||
198 | if (!tty) | ||
199 | return -ENODEV; | ||
200 | 209 | ||
201 | while (!(rd_regl(port, SIRFUART_RX_FIFO_STATUS) & | 210 | while (!(rd_regl(port, SIRFUART_RX_FIFO_STATUS) & |
202 | SIRFUART_FIFOEMPTY_MASK(port))) { | 211 | SIRFUART_FIFOEMPTY_MASK(port))) { |
@@ -210,8 +219,7 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | |||
210 | } | 219 | } |
211 | 220 | ||
212 | port->icount.rx += rx_count; | 221 | port->icount.rx += rx_count; |
213 | tty_flip_buffer_push(tty); | 222 | tty_flip_buffer_push(&port->state->port); |
214 | tty_kref_put(tty); | ||
215 | 223 | ||
216 | return rx_count; | 224 | return rx_count; |
217 | } | 225 | } |
@@ -245,6 +253,7 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | |||
245 | struct uart_port *port = &sirfport->port; | 253 | struct uart_port *port = &sirfport->port; |
246 | struct uart_state *state = port->state; | 254 | struct uart_state *state = port->state; |
247 | struct circ_buf *xmit = &port->state->xmit; | 255 | struct circ_buf *xmit = &port->state->xmit; |
256 | spin_lock(&port->lock); | ||
248 | intr_status = rd_regl(port, SIRFUART_INT_STATUS); | 257 | intr_status = rd_regl(port, SIRFUART_INT_STATUS); |
249 | wr_regl(port, SIRFUART_INT_STATUS, intr_status); | 258 | wr_regl(port, SIRFUART_INT_STATUS, intr_status); |
250 | intr_status &= rd_regl(port, SIRFUART_INT_EN); | 259 | intr_status &= rd_regl(port, SIRFUART_INT_EN); |
@@ -254,6 +263,7 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | |||
254 | goto recv_char; | 263 | goto recv_char; |
255 | uart_insert_char(port, intr_status, | 264 | uart_insert_char(port, intr_status, |
256 | SIRFUART_RX_OFLOW, 0, TTY_BREAK); | 265 | SIRFUART_RX_OFLOW, 0, TTY_BREAK); |
266 | spin_unlock(&port->lock); | ||
257 | return IRQ_HANDLED; | 267 | return IRQ_HANDLED; |
258 | } | 268 | } |
259 | if (intr_status & SIRFUART_RX_OFLOW) | 269 | if (intr_status & SIRFUART_RX_OFLOW) |
@@ -286,6 +296,7 @@ recv_char: | |||
286 | sirfsoc_uart_pio_rx_chars(port, SIRFSOC_UART_IO_RX_MAX_CNT); | 296 | sirfsoc_uart_pio_rx_chars(port, SIRFSOC_UART_IO_RX_MAX_CNT); |
287 | if (intr_status & SIRFUART_TX_INT_EN) { | 297 | if (intr_status & SIRFUART_TX_INT_EN) { |
288 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | 298 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { |
299 | spin_unlock(&port->lock); | ||
289 | return IRQ_HANDLED; | 300 | return IRQ_HANDLED; |
290 | } else { | 301 | } else { |
291 | sirfsoc_uart_pio_tx_chars(sirfport, | 302 | sirfsoc_uart_pio_tx_chars(sirfport, |
@@ -296,6 +307,7 @@ recv_char: | |||
296 | sirfsoc_uart_stop_tx(port); | 307 | sirfsoc_uart_stop_tx(port); |
297 | } | 308 | } |
298 | } | 309 | } |
310 | spin_unlock(&port->lock); | ||
299 | return IRQ_HANDLED; | 311 | return IRQ_HANDLED; |
300 | } | 312 | } |
301 | 313 | ||
@@ -345,7 +357,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
345 | struct ktermios *old) | 357 | struct ktermios *old) |
346 | { | 358 | { |
347 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 359 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
348 | unsigned long ioclk_rate; | ||
349 | unsigned long config_reg = 0; | 360 | unsigned long config_reg = 0; |
350 | unsigned long baud_rate; | 361 | unsigned long baud_rate; |
351 | unsigned long setted_baud; | 362 | unsigned long setted_baud; |
@@ -357,7 +368,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
357 | int threshold_div; | 368 | int threshold_div; |
358 | int temp; | 369 | int temp; |
359 | 370 | ||
360 | ioclk_rate = 150000000; | ||
361 | switch (termios->c_cflag & CSIZE) { | 371 | switch (termios->c_cflag & CSIZE) { |
362 | default: | 372 | default: |
363 | case CS8: | 373 | case CS8: |
@@ -413,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
413 | sirfsoc_uart_disable_ms(port); | 423 | sirfsoc_uart_disable_ms(port); |
414 | } | 424 | } |
415 | 425 | ||
416 | /* common rate: fast calculation */ | 426 | if (port->uartclk == 150000000) { |
417 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) | 427 | /* common rate: fast calculation */ |
418 | if (baud_rate == baudrate_to_regv[ic].baud_rate) | 428 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) |
419 | clk_div_reg = baudrate_to_regv[ic].reg_val; | 429 | if (baud_rate == baudrate_to_regv[ic].baud_rate) |
430 | clk_div_reg = baudrate_to_regv[ic].reg_val; | ||
431 | } | ||
432 | |||
420 | setted_baud = baud_rate; | 433 | setted_baud = baud_rate; |
421 | /* arbitary rate setting */ | 434 | /* arbitary rate setting */ |
422 | if (unlikely(clk_div_reg == 0)) | 435 | if (unlikely(clk_div_reg == 0)) |
423 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate, | 436 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, port->uartclk, |
424 | &setted_baud); | 437 | &setted_baud); |
425 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); | 438 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); |
426 | 439 | ||
@@ -679,6 +692,14 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
679 | goto err; | 692 | goto err; |
680 | } | 693 | } |
681 | 694 | ||
695 | sirfport->clk = clk_get(&pdev->dev, NULL); | ||
696 | if (IS_ERR(sirfport->clk)) { | ||
697 | ret = PTR_ERR(sirfport->clk); | ||
698 | goto clk_err; | ||
699 | } | ||
700 | clk_prepare_enable(sirfport->clk); | ||
701 | port->uartclk = clk_get_rate(sirfport->clk); | ||
702 | |||
682 | port->ops = &sirfsoc_uart_ops; | 703 | port->ops = &sirfsoc_uart_ops; |
683 | spin_lock_init(&port->lock); | 704 | spin_lock_init(&port->lock); |
684 | 705 | ||
@@ -692,6 +713,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
692 | return 0; | 713 | return 0; |
693 | 714 | ||
694 | port_err: | 715 | port_err: |
716 | clk_disable_unprepare(sirfport->clk); | ||
717 | clk_put(sirfport->clk); | ||
718 | clk_err: | ||
695 | platform_set_drvdata(pdev, NULL); | 719 | platform_set_drvdata(pdev, NULL); |
696 | if (sirfport->hw_flow_ctrl) | 720 | if (sirfport->hw_flow_ctrl) |
697 | pinctrl_put(sirfport->p); | 721 | pinctrl_put(sirfport->p); |
@@ -706,6 +730,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) | |||
706 | platform_set_drvdata(pdev, NULL); | 730 | platform_set_drvdata(pdev, NULL); |
707 | if (sirfport->hw_flow_ctrl) | 731 | if (sirfport->hw_flow_ctrl) |
708 | pinctrl_put(sirfport->p); | 732 | pinctrl_put(sirfport->p); |
733 | clk_disable_unprepare(sirfport->clk); | ||
734 | clk_put(sirfport->clk); | ||
709 | uart_remove_one_port(&sirfsoc_uart_drv, port); | 735 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
710 | return 0; | 736 | return 0; |
711 | } | 737 | } |
@@ -729,6 +755,7 @@ static int sirfsoc_uart_resume(struct platform_device *pdev) | |||
729 | 755 | ||
730 | static struct of_device_id sirfsoc_uart_ids[] = { | 756 | static struct of_device_id sirfsoc_uart_ids[] = { |
731 | { .compatible = "sirf,prima2-uart", }, | 757 | { .compatible = "sirf,prima2-uart", }, |
758 | { .compatible = "sirf,marco-uart", }, | ||
732 | {} | 759 | {} |
733 | }; | 760 | }; |
734 | MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); | 761 | MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); |
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 6e207fdc2fed..85328ba0c4e3 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -139,7 +139,7 @@ | |||
139 | #define SIRFSOC_UART_MINOR 0 | 139 | #define SIRFSOC_UART_MINOR 0 |
140 | #define SIRFUART_PORT_NAME "sirfsoc-uart" | 140 | #define SIRFUART_PORT_NAME "sirfsoc-uart" |
141 | #define SIRFUART_MAP_SIZE 0x200 | 141 | #define SIRFUART_MAP_SIZE 0x200 |
142 | #define SIRFSOC_UART_NR 3 | 142 | #define SIRFSOC_UART_NR 5 |
143 | #define SIRFSOC_PORT_TYPE 0xa5 | 143 | #define SIRFSOC_PORT_TYPE 0xa5 |
144 | 144 | ||
145 | /* Baud Rate Calculation */ | 145 | /* Baud Rate Calculation */ |
@@ -163,6 +163,7 @@ struct sirfsoc_uart_port { | |||
163 | 163 | ||
164 | struct uart_port port; | 164 | struct uart_port port; |
165 | struct pinctrl *p; | 165 | struct pinctrl *p; |
166 | struct clk *clk; | ||
166 | }; | 167 | }; |
167 | 168 | ||
168 | /* Hardware Flow Control */ | 169 | /* Hardware Flow Control */ |
diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c index 1c6de9f58699..f51ffdc696fd 100644 --- a/drivers/tty/serial/sn_console.c +++ b/drivers/tty/serial/sn_console.c | |||
@@ -457,8 +457,8 @@ static int sn_debug_printf(const char *fmt, ...) | |||
457 | static void | 457 | static void |
458 | sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | 458 | sn_receive_chars(struct sn_cons_port *port, unsigned long flags) |
459 | { | 459 | { |
460 | struct tty_port *tport = NULL; | ||
460 | int ch; | 461 | int ch; |
461 | struct tty_struct *tty; | ||
462 | 462 | ||
463 | if (!port) { | 463 | if (!port) { |
464 | printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n"); | 464 | printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n"); |
@@ -472,11 +472,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
472 | 472 | ||
473 | if (port->sc_port.state) { | 473 | if (port->sc_port.state) { |
474 | /* The serial_core stuffs are initialized, use them */ | 474 | /* The serial_core stuffs are initialized, use them */ |
475 | tty = port->sc_port.state->port.tty; | 475 | tport = &port->sc_port.state->port; |
476 | } | ||
477 | else { | ||
478 | /* Not registered yet - can't pass to tty layer. */ | ||
479 | tty = NULL; | ||
480 | } | 476 | } |
481 | 477 | ||
482 | while (port->sc_ops->sal_input_pending()) { | 478 | while (port->sc_ops->sal_input_pending()) { |
@@ -516,15 +512,15 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
516 | #endif /* CONFIG_MAGIC_SYSRQ */ | 512 | #endif /* CONFIG_MAGIC_SYSRQ */ |
517 | 513 | ||
518 | /* record the character to pass up to the tty layer */ | 514 | /* record the character to pass up to the tty layer */ |
519 | if (tty) { | 515 | if (tport) { |
520 | if(tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) | 516 | if (tty_insert_flip_char(tport, ch, TTY_NORMAL) == 0) |
521 | break; | 517 | break; |
522 | } | 518 | } |
523 | port->sc_port.icount.rx++; | 519 | port->sc_port.icount.rx++; |
524 | } | 520 | } |
525 | 521 | ||
526 | if (tty) | 522 | if (tport) |
527 | tty_flip_buffer_push(tty); | 523 | tty_flip_buffer_push(tport); |
528 | } | 524 | } |
529 | 525 | ||
530 | /** | 526 | /** |
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index b9bf9c53f7fd..ba60708053e0 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c | |||
@@ -72,7 +72,7 @@ static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit) | |||
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | 75 | static int receive_chars_getchar(struct uart_port *port) |
76 | { | 76 | { |
77 | int saw_console_brk = 0; | 77 | int saw_console_brk = 0; |
78 | int limit = 10000; | 78 | int limit = 10000; |
@@ -99,7 +99,7 @@ static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | |||
99 | uart_handle_dcd_change(port, 1); | 99 | uart_handle_dcd_change(port, 1); |
100 | } | 100 | } |
101 | 101 | ||
102 | if (tty == NULL) { | 102 | if (port->state == NULL) { |
103 | uart_handle_sysrq_char(port, c); | 103 | uart_handle_sysrq_char(port, c); |
104 | continue; | 104 | continue; |
105 | } | 105 | } |
@@ -109,13 +109,13 @@ static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | |||
109 | if (uart_handle_sysrq_char(port, c)) | 109 | if (uart_handle_sysrq_char(port, c)) |
110 | continue; | 110 | continue; |
111 | 111 | ||
112 | tty_insert_flip_char(tty, c, TTY_NORMAL); | 112 | tty_insert_flip_char(&port->state->port, c, TTY_NORMAL); |
113 | } | 113 | } |
114 | 114 | ||
115 | return saw_console_brk; | 115 | return saw_console_brk; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | 118 | static int receive_chars_read(struct uart_port *port) |
119 | { | 119 | { |
120 | int saw_console_brk = 0; | 120 | int saw_console_brk = 0; |
121 | int limit = 10000; | 121 | int limit = 10000; |
@@ -152,12 +152,13 @@ static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | |||
152 | for (i = 0; i < bytes_read; i++) | 152 | for (i = 0; i < bytes_read; i++) |
153 | uart_handle_sysrq_char(port, con_read_page[i]); | 153 | uart_handle_sysrq_char(port, con_read_page[i]); |
154 | 154 | ||
155 | if (tty == NULL) | 155 | if (port->state == NULL) |
156 | continue; | 156 | continue; |
157 | 157 | ||
158 | port->icount.rx += bytes_read; | 158 | port->icount.rx += bytes_read; |
159 | 159 | ||
160 | tty_insert_flip_string(tty, con_read_page, bytes_read); | 160 | tty_insert_flip_string(&port->state->port, con_read_page, |
161 | bytes_read); | ||
161 | } | 162 | } |
162 | 163 | ||
163 | return saw_console_brk; | 164 | return saw_console_brk; |
@@ -165,7 +166,7 @@ static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | |||
165 | 166 | ||
166 | struct sunhv_ops { | 167 | struct sunhv_ops { |
167 | void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit); | 168 | void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit); |
168 | int (*receive_chars)(struct uart_port *port, struct tty_struct *tty); | 169 | int (*receive_chars)(struct uart_port *port); |
169 | }; | 170 | }; |
170 | 171 | ||
171 | static struct sunhv_ops bychar_ops = { | 172 | static struct sunhv_ops bychar_ops = { |
@@ -180,17 +181,17 @@ static struct sunhv_ops bywrite_ops = { | |||
180 | 181 | ||
181 | static struct sunhv_ops *sunhv_ops = &bychar_ops; | 182 | static struct sunhv_ops *sunhv_ops = &bychar_ops; |
182 | 183 | ||
183 | static struct tty_struct *receive_chars(struct uart_port *port) | 184 | static struct tty_port *receive_chars(struct uart_port *port) |
184 | { | 185 | { |
185 | struct tty_struct *tty = NULL; | 186 | struct tty_port *tport = NULL; |
186 | 187 | ||
187 | if (port->state != NULL) /* Unopened serial console */ | 188 | if (port->state != NULL) /* Unopened serial console */ |
188 | tty = port->state->port.tty; | 189 | tport = &port->state->port; |
189 | 190 | ||
190 | if (sunhv_ops->receive_chars(port, tty)) | 191 | if (sunhv_ops->receive_chars(port)) |
191 | sun_do_break(); | 192 | sun_do_break(); |
192 | 193 | ||
193 | return tty; | 194 | return tport; |
194 | } | 195 | } |
195 | 196 | ||
196 | static void transmit_chars(struct uart_port *port) | 197 | static void transmit_chars(struct uart_port *port) |
@@ -213,16 +214,16 @@ static void transmit_chars(struct uart_port *port) | |||
213 | static irqreturn_t sunhv_interrupt(int irq, void *dev_id) | 214 | static irqreturn_t sunhv_interrupt(int irq, void *dev_id) |
214 | { | 215 | { |
215 | struct uart_port *port = dev_id; | 216 | struct uart_port *port = dev_id; |
216 | struct tty_struct *tty; | 217 | struct tty_port *tport; |
217 | unsigned long flags; | 218 | unsigned long flags; |
218 | 219 | ||
219 | spin_lock_irqsave(&port->lock, flags); | 220 | spin_lock_irqsave(&port->lock, flags); |
220 | tty = receive_chars(port); | 221 | tport = receive_chars(port); |
221 | transmit_chars(port); | 222 | transmit_chars(port); |
222 | spin_unlock_irqrestore(&port->lock, flags); | 223 | spin_unlock_irqrestore(&port->lock, flags); |
223 | 224 | ||
224 | if (tty) | 225 | if (tport) |
225 | tty_flip_buffer_push(tty); | 226 | tty_flip_buffer_push(tport); |
226 | 227 | ||
227 | return IRQ_HANDLED; | 228 | return IRQ_HANDLED; |
228 | } | 229 | } |
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index bd8b3b634103..8de2213664e0 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c | |||
@@ -107,11 +107,11 @@ static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up) | |||
107 | udelay(1); | 107 | udelay(1); |
108 | } | 108 | } |
109 | 109 | ||
110 | static struct tty_struct * | 110 | static struct tty_port * |
111 | receive_chars(struct uart_sunsab_port *up, | 111 | receive_chars(struct uart_sunsab_port *up, |
112 | union sab82532_irq_status *stat) | 112 | union sab82532_irq_status *stat) |
113 | { | 113 | { |
114 | struct tty_struct *tty = NULL; | 114 | struct tty_port *port = NULL; |
115 | unsigned char buf[32]; | 115 | unsigned char buf[32]; |
116 | int saw_console_brk = 0; | 116 | int saw_console_brk = 0; |
117 | int free_fifo = 0; | 117 | int free_fifo = 0; |
@@ -119,7 +119,7 @@ receive_chars(struct uart_sunsab_port *up, | |||
119 | int i; | 119 | int i; |
120 | 120 | ||
121 | if (up->port.state != NULL) /* Unopened serial console */ | 121 | if (up->port.state != NULL) /* Unopened serial console */ |
122 | tty = up->port.state->port.tty; | 122 | port = &up->port.state->port; |
123 | 123 | ||
124 | /* Read number of BYTES (Character + Status) available. */ | 124 | /* Read number of BYTES (Character + Status) available. */ |
125 | if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { | 125 | if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { |
@@ -136,7 +136,7 @@ receive_chars(struct uart_sunsab_port *up, | |||
136 | if (stat->sreg.isr0 & SAB82532_ISR0_TIME) { | 136 | if (stat->sreg.isr0 & SAB82532_ISR0_TIME) { |
137 | sunsab_cec_wait(up); | 137 | sunsab_cec_wait(up); |
138 | writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr); | 138 | writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr); |
139 | return tty; | 139 | return port; |
140 | } | 140 | } |
141 | 141 | ||
142 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) | 142 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) |
@@ -160,11 +160,6 @@ receive_chars(struct uart_sunsab_port *up, | |||
160 | for (i = 0; i < count; i++) { | 160 | for (i = 0; i < count; i++) { |
161 | unsigned char ch = buf[i], flag; | 161 | unsigned char ch = buf[i], flag; |
162 | 162 | ||
163 | if (tty == NULL) { | ||
164 | uart_handle_sysrq_char(&up->port, ch); | ||
165 | continue; | ||
166 | } | ||
167 | |||
168 | flag = TTY_NORMAL; | 163 | flag = TTY_NORMAL; |
169 | up->port.icount.rx++; | 164 | up->port.icount.rx++; |
170 | 165 | ||
@@ -213,15 +208,15 @@ receive_chars(struct uart_sunsab_port *up, | |||
213 | 208 | ||
214 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && | 209 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && |
215 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) | 210 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) |
216 | tty_insert_flip_char(tty, ch, flag); | 211 | tty_insert_flip_char(port, ch, flag); |
217 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) | 212 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) |
218 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 213 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
219 | } | 214 | } |
220 | 215 | ||
221 | if (saw_console_brk) | 216 | if (saw_console_brk) |
222 | sun_do_break(); | 217 | sun_do_break(); |
223 | 218 | ||
224 | return tty; | 219 | return port; |
225 | } | 220 | } |
226 | 221 | ||
227 | static void sunsab_stop_tx(struct uart_port *); | 222 | static void sunsab_stop_tx(struct uart_port *); |
@@ -304,7 +299,7 @@ static void check_status(struct uart_sunsab_port *up, | |||
304 | static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | 299 | static irqreturn_t sunsab_interrupt(int irq, void *dev_id) |
305 | { | 300 | { |
306 | struct uart_sunsab_port *up = dev_id; | 301 | struct uart_sunsab_port *up = dev_id; |
307 | struct tty_struct *tty; | 302 | struct tty_port *port = NULL; |
308 | union sab82532_irq_status status; | 303 | union sab82532_irq_status status; |
309 | unsigned long flags; | 304 | unsigned long flags; |
310 | unsigned char gis; | 305 | unsigned char gis; |
@@ -318,12 +313,11 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | |||
318 | if (gis & 2) | 313 | if (gis & 2) |
319 | status.sreg.isr1 = readb(&up->regs->r.isr1); | 314 | status.sreg.isr1 = readb(&up->regs->r.isr1); |
320 | 315 | ||
321 | tty = NULL; | ||
322 | if (status.stat) { | 316 | if (status.stat) { |
323 | if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | | 317 | if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | |
324 | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || | 318 | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || |
325 | (status.sreg.isr1 & SAB82532_ISR1_BRK)) | 319 | (status.sreg.isr1 & SAB82532_ISR1_BRK)) |
326 | tty = receive_chars(up, &status); | 320 | port = receive_chars(up, &status); |
327 | if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || | 321 | if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || |
328 | (status.sreg.isr1 & SAB82532_ISR1_CSC)) | 322 | (status.sreg.isr1 & SAB82532_ISR1_CSC)) |
329 | check_status(up, &status); | 323 | check_status(up, &status); |
@@ -333,8 +327,8 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | |||
333 | 327 | ||
334 | spin_unlock_irqrestore(&up->port.lock, flags); | 328 | spin_unlock_irqrestore(&up->port.lock, flags); |
335 | 329 | ||
336 | if (tty) | 330 | if (port) |
337 | tty_flip_buffer_push(tty); | 331 | tty_flip_buffer_push(port); |
338 | 332 | ||
339 | return IRQ_HANDLED; | 333 | return IRQ_HANDLED; |
340 | } | 334 | } |
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 220da3f9724f..e343d6670854 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c | |||
@@ -315,10 +315,10 @@ static void sunsu_enable_ms(struct uart_port *port) | |||
315 | spin_unlock_irqrestore(&up->port.lock, flags); | 315 | spin_unlock_irqrestore(&up->port.lock, flags); |
316 | } | 316 | } |
317 | 317 | ||
318 | static struct tty_struct * | 318 | static void |
319 | receive_chars(struct uart_sunsu_port *up, unsigned char *status) | 319 | receive_chars(struct uart_sunsu_port *up, unsigned char *status) |
320 | { | 320 | { |
321 | struct tty_struct *tty = up->port.state->port.tty; | 321 | struct tty_port *port = &up->port.state->port; |
322 | unsigned char ch, flag; | 322 | unsigned char ch, flag; |
323 | int max_count = 256; | 323 | int max_count = 256; |
324 | int saw_console_brk = 0; | 324 | int saw_console_brk = 0; |
@@ -376,22 +376,20 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status) | |||
376 | if (uart_handle_sysrq_char(&up->port, ch)) | 376 | if (uart_handle_sysrq_char(&up->port, ch)) |
377 | goto ignore_char; | 377 | goto ignore_char; |
378 | if ((*status & up->port.ignore_status_mask) == 0) | 378 | if ((*status & up->port.ignore_status_mask) == 0) |
379 | tty_insert_flip_char(tty, ch, flag); | 379 | tty_insert_flip_char(port, ch, flag); |
380 | if (*status & UART_LSR_OE) | 380 | if (*status & UART_LSR_OE) |
381 | /* | 381 | /* |
382 | * Overrun is special, since it's reported | 382 | * Overrun is special, since it's reported |
383 | * immediately, and doesn't affect the current | 383 | * immediately, and doesn't affect the current |
384 | * character. | 384 | * character. |
385 | */ | 385 | */ |
386 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 386 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
387 | ignore_char: | 387 | ignore_char: |
388 | *status = serial_inp(up, UART_LSR); | 388 | *status = serial_inp(up, UART_LSR); |
389 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 389 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
390 | 390 | ||
391 | if (saw_console_brk) | 391 | if (saw_console_brk) |
392 | sun_do_break(); | 392 | sun_do_break(); |
393 | |||
394 | return tty; | ||
395 | } | 393 | } |
396 | 394 | ||
397 | static void transmit_chars(struct uart_sunsu_port *up) | 395 | static void transmit_chars(struct uart_sunsu_port *up) |
@@ -460,20 +458,16 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) | |||
460 | spin_lock_irqsave(&up->port.lock, flags); | 458 | spin_lock_irqsave(&up->port.lock, flags); |
461 | 459 | ||
462 | do { | 460 | do { |
463 | struct tty_struct *tty; | ||
464 | |||
465 | status = serial_inp(up, UART_LSR); | 461 | status = serial_inp(up, UART_LSR); |
466 | tty = NULL; | ||
467 | if (status & UART_LSR_DR) | 462 | if (status & UART_LSR_DR) |
468 | tty = receive_chars(up, &status); | 463 | receive_chars(up, &status); |
469 | check_modem_status(up); | 464 | check_modem_status(up); |
470 | if (status & UART_LSR_THRE) | 465 | if (status & UART_LSR_THRE) |
471 | transmit_chars(up); | 466 | transmit_chars(up); |
472 | 467 | ||
473 | spin_unlock_irqrestore(&up->port.lock, flags); | 468 | spin_unlock_irqrestore(&up->port.lock, flags); |
474 | 469 | ||
475 | if (tty) | 470 | tty_flip_buffer_push(&up->port.state->port); |
476 | tty_flip_buffer_push(tty); | ||
477 | 471 | ||
478 | spin_lock_irqsave(&up->port.lock, flags); | 472 | spin_lock_irqsave(&up->port.lock, flags); |
479 | 473 | ||
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index aef4fab957c3..27669ff3d446 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c | |||
@@ -323,17 +323,15 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up, | |||
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | static struct tty_struct * | 326 | static struct tty_port * |
327 | sunzilog_receive_chars(struct uart_sunzilog_port *up, | 327 | sunzilog_receive_chars(struct uart_sunzilog_port *up, |
328 | struct zilog_channel __iomem *channel) | 328 | struct zilog_channel __iomem *channel) |
329 | { | 329 | { |
330 | struct tty_struct *tty; | 330 | struct tty_port *port = NULL; |
331 | unsigned char ch, r1, flag; | 331 | unsigned char ch, r1, flag; |
332 | 332 | ||
333 | tty = NULL; | 333 | if (up->port.state != NULL) /* Unopened serial console */ |
334 | if (up->port.state != NULL && /* Unopened serial console */ | 334 | port = &up->port.state->port; |
335 | up->port.state->port.tty != NULL) /* Keyboard || mouse */ | ||
336 | tty = up->port.state->port.tty; | ||
337 | 335 | ||
338 | for (;;) { | 336 | for (;;) { |
339 | 337 | ||
@@ -366,11 +364,6 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
366 | continue; | 364 | continue; |
367 | } | 365 | } |
368 | 366 | ||
369 | if (tty == NULL) { | ||
370 | uart_handle_sysrq_char(&up->port, ch); | ||
371 | continue; | ||
372 | } | ||
373 | |||
374 | /* A real serial line, record the character and status. */ | 367 | /* A real serial line, record the character and status. */ |
375 | flag = TTY_NORMAL; | 368 | flag = TTY_NORMAL; |
376 | up->port.icount.rx++; | 369 | up->port.icount.rx++; |
@@ -400,13 +393,13 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
400 | 393 | ||
401 | if (up->port.ignore_status_mask == 0xff || | 394 | if (up->port.ignore_status_mask == 0xff || |
402 | (r1 & up->port.ignore_status_mask) == 0) { | 395 | (r1 & up->port.ignore_status_mask) == 0) { |
403 | tty_insert_flip_char(tty, ch, flag); | 396 | tty_insert_flip_char(port, ch, flag); |
404 | } | 397 | } |
405 | if (r1 & Rx_OVR) | 398 | if (r1 & Rx_OVR) |
406 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 399 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
407 | } | 400 | } |
408 | 401 | ||
409 | return tty; | 402 | return port; |
410 | } | 403 | } |
411 | 404 | ||
412 | static void sunzilog_status_handle(struct uart_sunzilog_port *up, | 405 | static void sunzilog_status_handle(struct uart_sunzilog_port *up, |
@@ -539,21 +532,21 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
539 | while (up) { | 532 | while (up) { |
540 | struct zilog_channel __iomem *channel | 533 | struct zilog_channel __iomem *channel |
541 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | 534 | = ZILOG_CHANNEL_FROM_PORT(&up->port); |
542 | struct tty_struct *tty; | 535 | struct tty_port *port; |
543 | unsigned char r3; | 536 | unsigned char r3; |
544 | 537 | ||
545 | spin_lock(&up->port.lock); | 538 | spin_lock(&up->port.lock); |
546 | r3 = read_zsreg(channel, R3); | 539 | r3 = read_zsreg(channel, R3); |
547 | 540 | ||
548 | /* Channel A */ | 541 | /* Channel A */ |
549 | tty = NULL; | 542 | port = NULL; |
550 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 543 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
551 | writeb(RES_H_IUS, &channel->control); | 544 | writeb(RES_H_IUS, &channel->control); |
552 | ZSDELAY(); | 545 | ZSDELAY(); |
553 | ZS_WSYNC(channel); | 546 | ZS_WSYNC(channel); |
554 | 547 | ||
555 | if (r3 & CHARxIP) | 548 | if (r3 & CHARxIP) |
556 | tty = sunzilog_receive_chars(up, channel); | 549 | port = sunzilog_receive_chars(up, channel); |
557 | if (r3 & CHAEXT) | 550 | if (r3 & CHAEXT) |
558 | sunzilog_status_handle(up, channel); | 551 | sunzilog_status_handle(up, channel); |
559 | if (r3 & CHATxIP) | 552 | if (r3 & CHATxIP) |
@@ -561,22 +554,22 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
561 | } | 554 | } |
562 | spin_unlock(&up->port.lock); | 555 | spin_unlock(&up->port.lock); |
563 | 556 | ||
564 | if (tty) | 557 | if (port) |
565 | tty_flip_buffer_push(tty); | 558 | tty_flip_buffer_push(port); |
566 | 559 | ||
567 | /* Channel B */ | 560 | /* Channel B */ |
568 | up = up->next; | 561 | up = up->next; |
569 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | 562 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); |
570 | 563 | ||
571 | spin_lock(&up->port.lock); | 564 | spin_lock(&up->port.lock); |
572 | tty = NULL; | 565 | port = NULL; |
573 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 566 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
574 | writeb(RES_H_IUS, &channel->control); | 567 | writeb(RES_H_IUS, &channel->control); |
575 | ZSDELAY(); | 568 | ZSDELAY(); |
576 | ZS_WSYNC(channel); | 569 | ZS_WSYNC(channel); |
577 | 570 | ||
578 | if (r3 & CHBRxIP) | 571 | if (r3 & CHBRxIP) |
579 | tty = sunzilog_receive_chars(up, channel); | 572 | port = sunzilog_receive_chars(up, channel); |
580 | if (r3 & CHBEXT) | 573 | if (r3 & CHBEXT) |
581 | sunzilog_status_handle(up, channel); | 574 | sunzilog_status_handle(up, channel); |
582 | if (r3 & CHBTxIP) | 575 | if (r3 & CHBTxIP) |
@@ -584,8 +577,8 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
584 | } | 577 | } |
585 | spin_unlock(&up->port.lock); | 578 | spin_unlock(&up->port.lock); |
586 | 579 | ||
587 | if (tty) | 580 | if (port) |
588 | tty_flip_buffer_push(tty); | 581 | tty_flip_buffer_push(port); |
589 | 582 | ||
590 | up = up->next; | 583 | up = up->next; |
591 | } | 584 | } |
diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 5be0d68feceb..6818410a2bea 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c | |||
@@ -91,16 +91,16 @@ static void timbuart_flush_buffer(struct uart_port *port) | |||
91 | 91 | ||
92 | static void timbuart_rx_chars(struct uart_port *port) | 92 | static void timbuart_rx_chars(struct uart_port *port) |
93 | { | 93 | { |
94 | struct tty_struct *tty = port->state->port.tty; | 94 | struct tty_port *tport = &port->state->port; |
95 | 95 | ||
96 | while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { | 96 | while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { |
97 | u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); | 97 | u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); |
98 | port->icount.rx++; | 98 | port->icount.rx++; |
99 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 99 | tty_insert_flip_char(tport, ch, TTY_NORMAL); |
100 | } | 100 | } |
101 | 101 | ||
102 | spin_unlock(&port->lock); | 102 | spin_unlock(&port->lock); |
103 | tty_flip_buffer_push(port->state->port.tty); | 103 | tty_flip_buffer_push(tport); |
104 | spin_lock(&port->lock); | 104 | spin_lock(&port->lock); |
105 | 105 | ||
106 | dev_dbg(port->dev, "%s - total read %d bytes\n", | 106 | dev_dbg(port->dev, "%s - total read %d bytes\n", |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 89eee43c4e2d..5f90ef24d475 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <asm/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
25 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
@@ -34,7 +34,7 @@ | |||
34 | * Register definitions | 34 | * Register definitions |
35 | * | 35 | * |
36 | * For register details see datasheet: | 36 | * For register details see datasheet: |
37 | * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf | 37 | * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #define ULITE_RX 0x00 | 40 | #define ULITE_RX 0x00 |
@@ -57,6 +57,54 @@ | |||
57 | #define ULITE_CONTROL_RST_RX 0x02 | 57 | #define ULITE_CONTROL_RST_RX 0x02 |
58 | #define ULITE_CONTROL_IE 0x10 | 58 | #define ULITE_CONTROL_IE 0x10 |
59 | 59 | ||
60 | struct uartlite_reg_ops { | ||
61 | u32 (*in)(void __iomem *addr); | ||
62 | void (*out)(u32 val, void __iomem *addr); | ||
63 | }; | ||
64 | |||
65 | static u32 uartlite_inbe32(void __iomem *addr) | ||
66 | { | ||
67 | return ioread32be(addr); | ||
68 | } | ||
69 | |||
70 | static void uartlite_outbe32(u32 val, void __iomem *addr) | ||
71 | { | ||
72 | iowrite32be(val, addr); | ||
73 | } | ||
74 | |||
75 | static struct uartlite_reg_ops uartlite_be = { | ||
76 | .in = uartlite_inbe32, | ||
77 | .out = uartlite_outbe32, | ||
78 | }; | ||
79 | |||
80 | static u32 uartlite_inle32(void __iomem *addr) | ||
81 | { | ||
82 | return ioread32(addr); | ||
83 | } | ||
84 | |||
85 | static void uartlite_outle32(u32 val, void __iomem *addr) | ||
86 | { | ||
87 | iowrite32(val, addr); | ||
88 | } | ||
89 | |||
90 | static struct uartlite_reg_ops uartlite_le = { | ||
91 | .in = uartlite_inle32, | ||
92 | .out = uartlite_outle32, | ||
93 | }; | ||
94 | |||
95 | static inline u32 uart_in32(u32 offset, struct uart_port *port) | ||
96 | { | ||
97 | struct uartlite_reg_ops *reg_ops = port->private_data; | ||
98 | |||
99 | return reg_ops->in(port->membase + offset); | ||
100 | } | ||
101 | |||
102 | static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) | ||
103 | { | ||
104 | struct uartlite_reg_ops *reg_ops = port->private_data; | ||
105 | |||
106 | reg_ops->out(val, port->membase + offset); | ||
107 | } | ||
60 | 108 | ||
61 | static struct uart_port ulite_ports[ULITE_NR_UARTS]; | 109 | static struct uart_port ulite_ports[ULITE_NR_UARTS]; |
62 | 110 | ||
@@ -66,7 +114,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS]; | |||
66 | 114 | ||
67 | static int ulite_receive(struct uart_port *port, int stat) | 115 | static int ulite_receive(struct uart_port *port, int stat) |
68 | { | 116 | { |
69 | struct tty_struct *tty = port->state->port.tty; | 117 | struct tty_port *tport = &port->state->port; |
70 | unsigned char ch = 0; | 118 | unsigned char ch = 0; |
71 | char flag = TTY_NORMAL; | 119 | char flag = TTY_NORMAL; |
72 | 120 | ||
@@ -77,7 +125,7 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
77 | /* stats */ | 125 | /* stats */ |
78 | if (stat & ULITE_STATUS_RXVALID) { | 126 | if (stat & ULITE_STATUS_RXVALID) { |
79 | port->icount.rx++; | 127 | port->icount.rx++; |
80 | ch = ioread32be(port->membase + ULITE_RX); | 128 | ch = uart_in32(ULITE_RX, port); |
81 | 129 | ||
82 | if (stat & ULITE_STATUS_PARITY) | 130 | if (stat & ULITE_STATUS_PARITY) |
83 | port->icount.parity++; | 131 | port->icount.parity++; |
@@ -103,13 +151,13 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
103 | stat &= ~port->ignore_status_mask; | 151 | stat &= ~port->ignore_status_mask; |
104 | 152 | ||
105 | if (stat & ULITE_STATUS_RXVALID) | 153 | if (stat & ULITE_STATUS_RXVALID) |
106 | tty_insert_flip_char(tty, ch, flag); | 154 | tty_insert_flip_char(tport, ch, flag); |
107 | 155 | ||
108 | if (stat & ULITE_STATUS_FRAME) | 156 | if (stat & ULITE_STATUS_FRAME) |
109 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 157 | tty_insert_flip_char(tport, 0, TTY_FRAME); |
110 | 158 | ||
111 | if (stat & ULITE_STATUS_OVERRUN) | 159 | if (stat & ULITE_STATUS_OVERRUN) |
112 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 160 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
113 | 161 | ||
114 | return 1; | 162 | return 1; |
115 | } | 163 | } |
@@ -122,7 +170,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
122 | return 0; | 170 | return 0; |
123 | 171 | ||
124 | if (port->x_char) { | 172 | if (port->x_char) { |
125 | iowrite32be(port->x_char, port->membase + ULITE_TX); | 173 | uart_out32(port->x_char, ULITE_TX, port); |
126 | port->x_char = 0; | 174 | port->x_char = 0; |
127 | port->icount.tx++; | 175 | port->icount.tx++; |
128 | return 1; | 176 | return 1; |
@@ -131,7 +179,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
131 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 179 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
132 | return 0; | 180 | return 0; |
133 | 181 | ||
134 | iowrite32be(xmit->buf[xmit->tail], port->membase + ULITE_TX); | 182 | uart_out32(xmit->buf[xmit->tail], ULITE_TX, port); |
135 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); | 183 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); |
136 | port->icount.tx++; | 184 | port->icount.tx++; |
137 | 185 | ||
@@ -148,7 +196,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) | |||
148 | int busy, n = 0; | 196 | int busy, n = 0; |
149 | 197 | ||
150 | do { | 198 | do { |
151 | int stat = ioread32be(port->membase + ULITE_STATUS); | 199 | int stat = uart_in32(ULITE_STATUS, port); |
152 | busy = ulite_receive(port, stat); | 200 | busy = ulite_receive(port, stat); |
153 | busy |= ulite_transmit(port, stat); | 201 | busy |= ulite_transmit(port, stat); |
154 | n++; | 202 | n++; |
@@ -156,7 +204,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) | |||
156 | 204 | ||
157 | /* work done? */ | 205 | /* work done? */ |
158 | if (n > 1) { | 206 | if (n > 1) { |
159 | tty_flip_buffer_push(port->state->port.tty); | 207 | tty_flip_buffer_push(&port->state->port); |
160 | return IRQ_HANDLED; | 208 | return IRQ_HANDLED; |
161 | } else { | 209 | } else { |
162 | return IRQ_NONE; | 210 | return IRQ_NONE; |
@@ -169,7 +217,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port) | |||
169 | unsigned int ret; | 217 | unsigned int ret; |
170 | 218 | ||
171 | spin_lock_irqsave(&port->lock, flags); | 219 | spin_lock_irqsave(&port->lock, flags); |
172 | ret = ioread32be(port->membase + ULITE_STATUS); | 220 | ret = uart_in32(ULITE_STATUS, port); |
173 | spin_unlock_irqrestore(&port->lock, flags); | 221 | spin_unlock_irqrestore(&port->lock, flags); |
174 | 222 | ||
175 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; | 223 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; |
@@ -192,7 +240,7 @@ static void ulite_stop_tx(struct uart_port *port) | |||
192 | 240 | ||
193 | static void ulite_start_tx(struct uart_port *port) | 241 | static void ulite_start_tx(struct uart_port *port) |
194 | { | 242 | { |
195 | ulite_transmit(port, ioread32be(port->membase + ULITE_STATUS)); | 243 | ulite_transmit(port, uart_in32(ULITE_STATUS, port)); |
196 | } | 244 | } |
197 | 245 | ||
198 | static void ulite_stop_rx(struct uart_port *port) | 246 | static void ulite_stop_rx(struct uart_port *port) |
@@ -220,17 +268,17 @@ static int ulite_startup(struct uart_port *port) | |||
220 | if (ret) | 268 | if (ret) |
221 | return ret; | 269 | return ret; |
222 | 270 | ||
223 | iowrite32be(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, | 271 | uart_out32(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, |
224 | port->membase + ULITE_CONTROL); | 272 | ULITE_CONTROL, port); |
225 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 273 | uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port); |
226 | 274 | ||
227 | return 0; | 275 | return 0; |
228 | } | 276 | } |
229 | 277 | ||
230 | static void ulite_shutdown(struct uart_port *port) | 278 | static void ulite_shutdown(struct uart_port *port) |
231 | { | 279 | { |
232 | iowrite32be(0, port->membase + ULITE_CONTROL); | 280 | uart_out32(0, ULITE_CONTROL, port); |
233 | ioread32be(port->membase + ULITE_CONTROL); /* dummy */ | 281 | uart_in32(ULITE_CONTROL, port); /* dummy */ |
234 | free_irq(port->irq, port); | 282 | free_irq(port->irq, port); |
235 | } | 283 | } |
236 | 284 | ||
@@ -281,6 +329,8 @@ static void ulite_release_port(struct uart_port *port) | |||
281 | 329 | ||
282 | static int ulite_request_port(struct uart_port *port) | 330 | static int ulite_request_port(struct uart_port *port) |
283 | { | 331 | { |
332 | int ret; | ||
333 | |||
284 | pr_debug("ulite console: port=%p; port->mapbase=%llx\n", | 334 | pr_debug("ulite console: port=%p; port->mapbase=%llx\n", |
285 | port, (unsigned long long) port->mapbase); | 335 | port, (unsigned long long) port->mapbase); |
286 | 336 | ||
@@ -296,6 +346,14 @@ static int ulite_request_port(struct uart_port *port) | |||
296 | return -EBUSY; | 346 | return -EBUSY; |
297 | } | 347 | } |
298 | 348 | ||
349 | port->private_data = &uartlite_be; | ||
350 | ret = uart_in32(ULITE_CONTROL, port); | ||
351 | uart_out32(ULITE_CONTROL_RST_TX, ULITE_CONTROL, port); | ||
352 | ret = uart_in32(ULITE_STATUS, port); | ||
353 | /* Endianess detection */ | ||
354 | if ((ret & ULITE_STATUS_TXEMPTY) != ULITE_STATUS_TXEMPTY) | ||
355 | port->private_data = &uartlite_le; | ||
356 | |||
299 | return 0; | 357 | return 0; |
300 | } | 358 | } |
301 | 359 | ||
@@ -314,20 +372,19 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
314 | #ifdef CONFIG_CONSOLE_POLL | 372 | #ifdef CONFIG_CONSOLE_POLL |
315 | static int ulite_get_poll_char(struct uart_port *port) | 373 | static int ulite_get_poll_char(struct uart_port *port) |
316 | { | 374 | { |
317 | if (!(ioread32be(port->membase + ULITE_STATUS) | 375 | if (!(uart_in32(ULITE_STATUS, port) & ULITE_STATUS_RXVALID)) |
318 | & ULITE_STATUS_RXVALID)) | ||
319 | return NO_POLL_CHAR; | 376 | return NO_POLL_CHAR; |
320 | 377 | ||
321 | return ioread32be(port->membase + ULITE_RX); | 378 | return uart_in32(ULITE_RX, port); |
322 | } | 379 | } |
323 | 380 | ||
324 | static void ulite_put_poll_char(struct uart_port *port, unsigned char ch) | 381 | static void ulite_put_poll_char(struct uart_port *port, unsigned char ch) |
325 | { | 382 | { |
326 | while (ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_TXFULL) | 383 | while (uart_in32(ULITE_STATUS, port) & ULITE_STATUS_TXFULL) |
327 | cpu_relax(); | 384 | cpu_relax(); |
328 | 385 | ||
329 | /* write char to device */ | 386 | /* write char to device */ |
330 | iowrite32be(ch, port->membase + ULITE_TX); | 387 | uart_out32(ch, ULITE_TX, port); |
331 | } | 388 | } |
332 | #endif | 389 | #endif |
333 | 390 | ||
@@ -366,7 +423,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
366 | 423 | ||
367 | /* Spin waiting for TX fifo to have space available */ | 424 | /* Spin waiting for TX fifo to have space available */ |
368 | for (i = 0; i < 100000; i++) { | 425 | for (i = 0; i < 100000; i++) { |
369 | val = ioread32be(port->membase + ULITE_STATUS); | 426 | val = uart_in32(ULITE_STATUS, port); |
370 | if ((val & ULITE_STATUS_TXFULL) == 0) | 427 | if ((val & ULITE_STATUS_TXFULL) == 0) |
371 | break; | 428 | break; |
372 | cpu_relax(); | 429 | cpu_relax(); |
@@ -376,7 +433,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
376 | static void ulite_console_putchar(struct uart_port *port, int ch) | 433 | static void ulite_console_putchar(struct uart_port *port, int ch) |
377 | { | 434 | { |
378 | ulite_console_wait_tx(port); | 435 | ulite_console_wait_tx(port); |
379 | iowrite32be(ch, port->membase + ULITE_TX); | 436 | uart_out32(ch, ULITE_TX, port); |
380 | } | 437 | } |
381 | 438 | ||
382 | static void ulite_console_write(struct console *co, const char *s, | 439 | static void ulite_console_write(struct console *co, const char *s, |
@@ -393,8 +450,8 @@ static void ulite_console_write(struct console *co, const char *s, | |||
393 | spin_lock_irqsave(&port->lock, flags); | 450 | spin_lock_irqsave(&port->lock, flags); |
394 | 451 | ||
395 | /* save and disable interrupt */ | 452 | /* save and disable interrupt */ |
396 | ier = ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; | 453 | ier = uart_in32(ULITE_STATUS, port) & ULITE_STATUS_IE; |
397 | iowrite32be(0, port->membase + ULITE_CONTROL); | 454 | uart_out32(0, ULITE_CONTROL, port); |
398 | 455 | ||
399 | uart_console_write(port, s, count, ulite_console_putchar); | 456 | uart_console_write(port, s, count, ulite_console_putchar); |
400 | 457 | ||
@@ -402,7 +459,7 @@ static void ulite_console_write(struct console *co, const char *s, | |||
402 | 459 | ||
403 | /* restore interrupt state */ | 460 | /* restore interrupt state */ |
404 | if (ier) | 461 | if (ier) |
405 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 462 | uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port); |
406 | 463 | ||
407 | if (locked) | 464 | if (locked) |
408 | spin_unlock_irqrestore(&port->lock, flags); | 465 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -615,7 +672,7 @@ static struct platform_driver ulite_platform_driver = { | |||
615 | * Module setup/teardown | 672 | * Module setup/teardown |
616 | */ | 673 | */ |
617 | 674 | ||
618 | int __init ulite_init(void) | 675 | static int __init ulite_init(void) |
619 | { | 676 | { |
620 | int ret; | 677 | int ret; |
621 | 678 | ||
@@ -634,11 +691,11 @@ int __init ulite_init(void) | |||
634 | err_plat: | 691 | err_plat: |
635 | uart_unregister_driver(&ulite_uart_driver); | 692 | uart_unregister_driver(&ulite_uart_driver); |
636 | err_uart: | 693 | err_uart: |
637 | printk(KERN_ERR "registering uartlite driver failed: err=%i", ret); | 694 | pr_err("registering uartlite driver failed: err=%i", ret); |
638 | return ret; | 695 | return ret; |
639 | } | 696 | } |
640 | 697 | ||
641 | void __exit ulite_exit(void) | 698 | static void __exit ulite_exit(void) |
642 | { | 699 | { |
643 | platform_driver_unregister(&ulite_platform_driver); | 700 | platform_driver_unregister(&ulite_platform_driver); |
644 | uart_unregister_driver(&ulite_uart_driver); | 701 | uart_unregister_driver(&ulite_uart_driver); |
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index f99b0c965f85..7355303dad99 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c | |||
@@ -469,7 +469,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
469 | int i; | 469 | int i; |
470 | unsigned char ch, *cp; | 470 | unsigned char ch, *cp; |
471 | struct uart_port *port = &qe_port->port; | 471 | struct uart_port *port = &qe_port->port; |
472 | struct tty_struct *tty = port->state->port.tty; | 472 | struct tty_port *tport = &port->state->port; |
473 | struct qe_bd *bdp; | 473 | struct qe_bd *bdp; |
474 | u16 status; | 474 | u16 status; |
475 | unsigned int flg; | 475 | unsigned int flg; |
@@ -491,7 +491,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
491 | /* If we don't have enough room in RX buffer for the entire BD, | 491 | /* If we don't have enough room in RX buffer for the entire BD, |
492 | * then we try later, which will be the next RX interrupt. | 492 | * then we try later, which will be the next RX interrupt. |
493 | */ | 493 | */ |
494 | if (tty_buffer_request_room(tty, i) < i) { | 494 | if (tty_buffer_request_room(tport, i) < i) { |
495 | dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n"); | 495 | dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n"); |
496 | return; | 496 | return; |
497 | } | 497 | } |
@@ -512,7 +512,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
512 | continue; | 512 | continue; |
513 | 513 | ||
514 | error_return: | 514 | error_return: |
515 | tty_insert_flip_char(tty, ch, flg); | 515 | tty_insert_flip_char(tport, ch, flg); |
516 | 516 | ||
517 | } | 517 | } |
518 | 518 | ||
@@ -530,7 +530,7 @@ error_return: | |||
530 | qe_port->rx_cur = bdp; | 530 | qe_port->rx_cur = bdp; |
531 | 531 | ||
532 | /* Activate BH processing */ | 532 | /* Activate BH processing */ |
533 | tty_flip_buffer_push(tty); | 533 | tty_flip_buffer_push(tport); |
534 | 534 | ||
535 | return; | 535 | return; |
536 | 536 | ||
@@ -560,7 +560,7 @@ handle_error: | |||
560 | 560 | ||
561 | /* Overrun does not affect the current character ! */ | 561 | /* Overrun does not affect the current character ! */ |
562 | if (status & BD_SC_OV) | 562 | if (status & BD_SC_OV) |
563 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 563 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
564 | #ifdef SUPPORT_SYSRQ | 564 | #ifdef SUPPORT_SYSRQ |
565 | port->sysrq = 0; | 565 | port->sysrq = 0; |
566 | #endif | 566 | #endif |
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 62ee0166bc65..f655997f44af 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c | |||
@@ -313,12 +313,10 @@ static void siu_break_ctl(struct uart_port *port, int ctl) | |||
313 | 313 | ||
314 | static inline void receive_chars(struct uart_port *port, uint8_t *status) | 314 | static inline void receive_chars(struct uart_port *port, uint8_t *status) |
315 | { | 315 | { |
316 | struct tty_struct *tty; | ||
317 | uint8_t lsr, ch; | 316 | uint8_t lsr, ch; |
318 | char flag; | 317 | char flag; |
319 | int max_count = RX_MAX_COUNT; | 318 | int max_count = RX_MAX_COUNT; |
320 | 319 | ||
321 | tty = port->state->port.tty; | ||
322 | lsr = *status; | 320 | lsr = *status; |
323 | 321 | ||
324 | do { | 322 | do { |
@@ -365,7 +363,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status) | |||
365 | lsr = siu_read(port, UART_LSR); | 363 | lsr = siu_read(port, UART_LSR); |
366 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); | 364 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); |
367 | 365 | ||
368 | tty_flip_buffer_push(tty); | 366 | tty_flip_buffer_push(&port->state->port); |
369 | 367 | ||
370 | *status = lsr; | 368 | *status = lsr; |
371 | } | 369 | } |
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index d5ed9f613005..a3f9dd5c9dff 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
@@ -136,22 +136,14 @@ static void vt8500_enable_ms(struct uart_port *port) | |||
136 | 136 | ||
137 | static void handle_rx(struct uart_port *port) | 137 | static void handle_rx(struct uart_port *port) |
138 | { | 138 | { |
139 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 139 | struct tty_port *tport = &port->state->port; |
140 | if (!tty) { | ||
141 | /* Discard data: no tty available */ | ||
142 | int count = (vt8500_read(port, VT8500_URFIDX) & 0x1f00) >> 8; | ||
143 | u16 ch; | ||
144 | while (count--) | ||
145 | ch = readw(port->membase + VT8500_RXFIFO); | ||
146 | return; | ||
147 | } | ||
148 | 140 | ||
149 | /* | 141 | /* |
150 | * Handle overrun | 142 | * Handle overrun |
151 | */ | 143 | */ |
152 | if ((vt8500_read(port, VT8500_URISR) & RXOVER)) { | 144 | if ((vt8500_read(port, VT8500_URISR) & RXOVER)) { |
153 | port->icount.overrun++; | 145 | port->icount.overrun++; |
154 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 146 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
155 | } | 147 | } |
156 | 148 | ||
157 | /* and now the main RX loop */ | 149 | /* and now the main RX loop */ |
@@ -174,11 +166,10 @@ static void handle_rx(struct uart_port *port) | |||
174 | port->icount.rx++; | 166 | port->icount.rx++; |
175 | 167 | ||
176 | if (!uart_handle_sysrq_char(port, c)) | 168 | if (!uart_handle_sysrq_char(port, c)) |
177 | tty_insert_flip_char(tty, c, flag); | 169 | tty_insert_flip_char(tport, c, flag); |
178 | } | 170 | } |
179 | 171 | ||
180 | tty_flip_buffer_push(tty); | 172 | tty_flip_buffer_push(tport); |
181 | tty_kref_put(tty); | ||
182 | } | 173 | } |
183 | 174 | ||
184 | static void handle_tx(struct uart_port *port) | 175 | static void handle_tx(struct uart_port *port) |
@@ -569,7 +560,7 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
569 | 560 | ||
570 | if (np) | 561 | if (np) |
571 | port = of_alias_get_id(np, "serial"); | 562 | port = of_alias_get_id(np, "serial"); |
572 | if (port > VT8500_MAX_PORTS) | 563 | if (port >= VT8500_MAX_PORTS) |
573 | port = -1; | 564 | port = -1; |
574 | else | 565 | else |
575 | port = -1; | 566 | port = -1; |
@@ -580,7 +571,7 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
580 | sizeof(vt8500_ports_in_use)); | 571 | sizeof(vt8500_ports_in_use)); |
581 | } | 572 | } |
582 | 573 | ||
583 | if (port > VT8500_MAX_PORTS) | 574 | if (port >= VT8500_MAX_PORTS) |
584 | return -ENODEV; | 575 | return -ENODEV; |
585 | 576 | ||
586 | /* reserve the port id */ | 577 | /* reserve the port id */ |
@@ -589,10 +580,27 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
589 | return -EBUSY; | 580 | return -EBUSY; |
590 | } | 581 | } |
591 | 582 | ||
592 | vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL); | 583 | vt8500_port = devm_kzalloc(&pdev->dev, sizeof(struct vt8500_port), |
584 | GFP_KERNEL); | ||
593 | if (!vt8500_port) | 585 | if (!vt8500_port) |
594 | return -ENOMEM; | 586 | return -ENOMEM; |
595 | 587 | ||
588 | vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres); | ||
589 | if (!vt8500_port->uart.membase) | ||
590 | return -EADDRNOTAVAIL; | ||
591 | |||
592 | vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); | ||
593 | if (IS_ERR(vt8500_port->clk)) { | ||
594 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
595 | return -EINVAL; | ||
596 | } | ||
597 | |||
598 | ret = clk_prepare_enable(vt8500_port->clk); | ||
599 | if (ret) { | ||
600 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
601 | return ret; | ||
602 | } | ||
603 | |||
596 | vt8500_port->uart.type = PORT_VT8500; | 604 | vt8500_port->uart.type = PORT_VT8500; |
597 | vt8500_port->uart.iotype = UPIO_MEM; | 605 | vt8500_port->uart.iotype = UPIO_MEM; |
598 | vt8500_port->uart.mapbase = mmres->start; | 606 | vt8500_port->uart.mapbase = mmres->start; |
@@ -615,12 +623,6 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
615 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), | 623 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), |
616 | "VT8500 UART%d", pdev->id); | 624 | "VT8500 UART%d", pdev->id); |
617 | 625 | ||
618 | vt8500_port->uart.membase = ioremap(mmres->start, resource_size(mmres)); | ||
619 | if (!vt8500_port->uart.membase) { | ||
620 | ret = -ENOMEM; | ||
621 | goto err; | ||
622 | } | ||
623 | |||
624 | vt8500_uart_ports[port] = vt8500_port; | 626 | vt8500_uart_ports[port] = vt8500_port; |
625 | 627 | ||
626 | uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); | 628 | uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); |
@@ -628,10 +630,6 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
628 | platform_set_drvdata(pdev, vt8500_port); | 630 | platform_set_drvdata(pdev, vt8500_port); |
629 | 631 | ||
630 | return 0; | 632 | return 0; |
631 | |||
632 | err: | ||
633 | kfree(vt8500_port); | ||
634 | return ret; | ||
635 | } | 633 | } |
636 | 634 | ||
637 | static int vt8500_serial_remove(struct platform_device *pdev) | 635 | static int vt8500_serial_remove(struct platform_device *pdev) |
@@ -639,8 +637,8 @@ static int vt8500_serial_remove(struct platform_device *pdev) | |||
639 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); | 637 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); |
640 | 638 | ||
641 | platform_set_drvdata(pdev, NULL); | 639 | platform_set_drvdata(pdev, NULL); |
640 | clk_disable_unprepare(vt8500_port->clk); | ||
642 | uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart); | 641 | uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart); |
643 | kfree(vt8500_port); | ||
644 | 642 | ||
645 | return 0; | 643 | return 0; |
646 | } | 644 | } |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 9ab910370c56..ba451c7209fc 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
18 | #include <linux/tty_flip.h> | 18 | #include <linux/tty_flip.h> |
19 | #include <linux/console.h> | 19 | #include <linux/console.h> |
20 | #include <linux/clk.h> | ||
20 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
@@ -147,15 +148,11 @@ | |||
147 | static irqreturn_t xuartps_isr(int irq, void *dev_id) | 148 | static irqreturn_t xuartps_isr(int irq, void *dev_id) |
148 | { | 149 | { |
149 | struct uart_port *port = (struct uart_port *)dev_id; | 150 | struct uart_port *port = (struct uart_port *)dev_id; |
150 | struct tty_struct *tty; | ||
151 | unsigned long flags; | 151 | unsigned long flags; |
152 | unsigned int isrstatus, numbytes; | 152 | unsigned int isrstatus, numbytes; |
153 | unsigned int data; | 153 | unsigned int data; |
154 | char status = TTY_NORMAL; | 154 | char status = TTY_NORMAL; |
155 | 155 | ||
156 | /* Get the tty which could be NULL so don't assume it's valid */ | ||
157 | tty = tty_port_tty_get(&port->state->port); | ||
158 | |||
159 | spin_lock_irqsave(&port->lock, flags); | 156 | spin_lock_irqsave(&port->lock, flags); |
160 | 157 | ||
161 | /* Read the interrupt status register to determine which | 158 | /* Read the interrupt status register to determine which |
@@ -187,14 +184,11 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) | |||
187 | } else if (isrstatus & XUARTPS_IXR_OVERRUN) | 184 | } else if (isrstatus & XUARTPS_IXR_OVERRUN) |
188 | port->icount.overrun++; | 185 | port->icount.overrun++; |
189 | 186 | ||
190 | if (tty) | 187 | uart_insert_char(port, isrstatus, XUARTPS_IXR_OVERRUN, |
191 | uart_insert_char(port, isrstatus, | 188 | data, status); |
192 | XUARTPS_IXR_OVERRUN, data, | ||
193 | status); | ||
194 | } | 189 | } |
195 | spin_unlock(&port->lock); | 190 | spin_unlock(&port->lock); |
196 | if (tty) | 191 | tty_flip_buffer_push(&port->state->port); |
197 | tty_flip_buffer_push(tty); | ||
198 | spin_lock(&port->lock); | 192 | spin_lock(&port->lock); |
199 | } | 193 | } |
200 | 194 | ||
@@ -237,7 +231,6 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) | |||
237 | 231 | ||
238 | /* be sure to release the lock and tty before leaving */ | 232 | /* be sure to release the lock and tty before leaving */ |
239 | spin_unlock_irqrestore(&port->lock, flags); | 233 | spin_unlock_irqrestore(&port->lock, flags); |
240 | tty_kref_put(tty); | ||
241 | 234 | ||
242 | return IRQ_HANDLED; | 235 | return IRQ_HANDLED; |
243 | } | 236 | } |
@@ -944,16 +937,18 @@ static int xuartps_probe(struct platform_device *pdev) | |||
944 | int rc; | 937 | int rc; |
945 | struct uart_port *port; | 938 | struct uart_port *port; |
946 | struct resource *res, *res2; | 939 | struct resource *res, *res2; |
947 | int clk = 0; | 940 | struct clk *clk; |
948 | |||
949 | const unsigned int *prop; | ||
950 | 941 | ||
951 | prop = of_get_property(pdev->dev.of_node, "clock", NULL); | 942 | clk = of_clk_get(pdev->dev.of_node, 0); |
952 | if (prop) | 943 | if (IS_ERR(clk)) { |
953 | clk = be32_to_cpup(prop); | ||
954 | if (!clk) { | ||
955 | dev_err(&pdev->dev, "no clock specified\n"); | 944 | dev_err(&pdev->dev, "no clock specified\n"); |
956 | return -ENODEV; | 945 | return PTR_ERR(clk); |
946 | } | ||
947 | |||
948 | rc = clk_prepare_enable(clk); | ||
949 | if (rc) { | ||
950 | dev_err(&pdev->dev, "could not enable clock\n"); | ||
951 | return -EBUSY; | ||
957 | } | 952 | } |
958 | 953 | ||
959 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 954 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -978,7 +973,8 @@ static int xuartps_probe(struct platform_device *pdev) | |||
978 | port->mapbase = res->start; | 973 | port->mapbase = res->start; |
979 | port->irq = res2->start; | 974 | port->irq = res2->start; |
980 | port->dev = &pdev->dev; | 975 | port->dev = &pdev->dev; |
981 | port->uartclk = clk; | 976 | port->uartclk = clk_get_rate(clk); |
977 | port->private_data = clk; | ||
982 | dev_set_drvdata(&pdev->dev, port); | 978 | dev_set_drvdata(&pdev->dev, port); |
983 | rc = uart_add_one_port(&xuartps_uart_driver, port); | 979 | rc = uart_add_one_port(&xuartps_uart_driver, port); |
984 | if (rc) { | 980 | if (rc) { |
@@ -1000,14 +996,14 @@ static int xuartps_probe(struct platform_device *pdev) | |||
1000 | static int xuartps_remove(struct platform_device *pdev) | 996 | static int xuartps_remove(struct platform_device *pdev) |
1001 | { | 997 | { |
1002 | struct uart_port *port = dev_get_drvdata(&pdev->dev); | 998 | struct uart_port *port = dev_get_drvdata(&pdev->dev); |
1003 | int rc = 0; | 999 | struct clk *clk = port->private_data; |
1000 | int rc; | ||
1004 | 1001 | ||
1005 | /* Remove the xuartps port from the serial core */ | 1002 | /* Remove the xuartps port from the serial core */ |
1006 | if (port) { | 1003 | rc = uart_remove_one_port(&xuartps_uart_driver, port); |
1007 | rc = uart_remove_one_port(&xuartps_uart_driver, port); | 1004 | dev_set_drvdata(&pdev->dev, NULL); |
1008 | dev_set_drvdata(&pdev->dev, NULL); | 1005 | port->mapbase = 0; |
1009 | port->mapbase = 0; | 1006 | clk_disable_unprepare(clk); |
1010 | } | ||
1011 | return rc; | 1007 | return rc; |
1012 | } | 1008 | } |
1013 | 1009 | ||
@@ -1048,7 +1044,7 @@ MODULE_DEVICE_TABLE(of, xuartps_of_match); | |||
1048 | 1044 | ||
1049 | static struct platform_driver xuartps_platform_driver = { | 1045 | static struct platform_driver xuartps_platform_driver = { |
1050 | .probe = xuartps_probe, /* Probe method */ | 1046 | .probe = xuartps_probe, /* Probe method */ |
1051 | .remove = __exit_p(xuartps_remove), /* Detach method */ | 1047 | .remove = xuartps_remove, /* Detach method */ |
1052 | .suspend = xuartps_suspend, /* Suspend */ | 1048 | .suspend = xuartps_suspend, /* Suspend */ |
1053 | .resume = xuartps_resume, /* Resume after a suspend */ | 1049 | .resume = xuartps_resume, /* Resume after a suspend */ |
1054 | .driver = { | 1050 | .driver = { |
diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index 92c00b24d0df..6a169877109b 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c | |||
@@ -603,7 +603,7 @@ static void zs_receive_chars(struct zs_port *zport) | |||
603 | uart_insert_char(uport, status, Rx_OVR, ch, flag); | 603 | uart_insert_char(uport, status, Rx_OVR, ch, flag); |
604 | } | 604 | } |
605 | 605 | ||
606 | tty_flip_buffer_push(uport->state->port.tty); | 606 | tty_flip_buffer_push(&uport->state->port); |
607 | } | 607 | } |
608 | 608 | ||
609 | static void zs_raw_transmit_chars(struct zs_port *zport) | 609 | static void zs_raw_transmit_chars(struct zs_port *zport) |