diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 15:09:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 15:09:24 -0500 |
commit | 5983faf942f260023e547f3c5f38c1033c35cc9b (patch) | |
tree | f54ce89de5d9f7a05e99948937ac5456df09df30 | |
parent | 21a2cb565a74bf794d343ce22300c5f6c1568ae1 (diff) | |
parent | 995234da19b927f42722d796e8270384f33be11c (diff) |
Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (65 commits)
tty: serial: imx: move del_timer_sync() to avoid potential deadlock
imx: add polled io uart methods
imx: Add save/restore functions for UART control regs
serial/imx: let probing fail for the dt case without a valid alias
serial/imx: propagate error from of_alias_get_id instead of using -ENODEV
tty: serial: imx: Allow UART to be a source for wakeup
serial: driver for m32 arch should not have DEC alpha errata
serial/documentation: fix documented name of DCD cpp symbol
atmel_serial: fix spinlock lockup in RS485 code
tty: Fix memory leak in virtual console when enable unicode translation
serial: use DIV_ROUND_CLOSEST instead of open coding it
serial: add support for 400 and 800 v3 series Titan cards
serial: bfin-uart: Remove ASYNC_CTS_FLOW flag for hardware automatic CTS.
serial: bfin-uart: Enable hardware automatic CTS only when CTS pin is available.
serial: make FSL errata depend on 8250_CONSOLE, not just 8250
serial: add irq handler for Freescale 16550 errata.
serial: manually inline serial8250_handle_port
serial: make 8250 timeout use the specified IRQ handler
serial: export the key functions for an 8250 IRQ handler
serial: clean up parameter passing for 8250 Rx IRQ handling
...
45 files changed, 1989 insertions, 658 deletions
diff --git a/Documentation/serial/driver b/Documentation/serial/driver index 77ba0afbe4db..0a25a9191864 100644 --- a/Documentation/serial/driver +++ b/Documentation/serial/driver | |||
@@ -101,7 +101,7 @@ hardware. | |||
101 | Returns the current state of modem control inputs. The state | 101 | Returns the current state of modem control inputs. The state |
102 | of the outputs should not be returned, since the core keeps | 102 | of the outputs should not be returned, since the core keeps |
103 | track of their state. The state information should include: | 103 | track of their state. The state information should include: |
104 | - TIOCM_DCD state of DCD signal | 104 | - TIOCM_CAR state of DCD signal |
105 | - TIOCM_CTS state of CTS signal | 105 | - TIOCM_CTS state of CTS signal |
106 | - TIOCM_DSR state of DSR signal | 106 | - TIOCM_DSR state of DSR signal |
107 | - TIOCM_RI state of RI signal | 107 | - TIOCM_RI state of RI signal |
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index c7b5afeecaf2..3fea3689527e 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -441,6 +441,9 @@ static void __init fixup_port_irq(int index, | |||
441 | return; | 441 | return; |
442 | 442 | ||
443 | port->irq = virq; | 443 | port->irq = virq; |
444 | |||
445 | if (of_device_is_compatible(np, "fsl,ns16550")) | ||
446 | port->handle_irq = fsl8250_handle_irq; | ||
444 | } | 447 | } |
445 | 448 | ||
446 | static void __init fixup_port_pio(int index, | 449 | static void __init fixup_port_pio(int index, |
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h index 93f79094c224..0a0a95460434 100644 --- a/arch/x86/include/asm/mrst.h +++ b/arch/x86/include/asm/mrst.h | |||
@@ -67,7 +67,7 @@ extern struct console early_mrst_console; | |||
67 | extern void mrst_early_console_init(void); | 67 | extern void mrst_early_console_init(void); |
68 | 68 | ||
69 | extern struct console early_hsu_console; | 69 | extern struct console early_hsu_console; |
70 | extern void hsu_early_console_init(void); | 70 | extern void hsu_early_console_init(const char *); |
71 | 71 | ||
72 | extern void intel_scu_devices_create(void); | 72 | extern void intel_scu_devices_create(void); |
73 | extern void intel_scu_devices_destroy(void); | 73 | extern void intel_scu_devices_destroy(void); |
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index cd28a350f7f9..9d42a52d2331 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
@@ -247,7 +247,7 @@ static int __init setup_early_printk(char *buf) | |||
247 | } | 247 | } |
248 | 248 | ||
249 | if (!strncmp(buf, "hsu", 3)) { | 249 | if (!strncmp(buf, "hsu", 3)) { |
250 | hsu_early_console_init(); | 250 | hsu_early_console_init(buf + 3); |
251 | early_console_register(&early_hsu_console, keep); | 251 | early_console_register(&early_hsu_console, keep); |
252 | } | 252 | } |
253 | #endif | 253 | #endif |
diff --git a/arch/x86/platform/mrst/early_printk_mrst.c b/arch/x86/platform/mrst/early_printk_mrst.c index 25bfdbb5b130..3c6e328483c7 100644 --- a/arch/x86/platform/mrst/early_printk_mrst.c +++ b/arch/x86/platform/mrst/early_printk_mrst.c | |||
@@ -245,16 +245,24 @@ struct console early_mrst_console = { | |||
245 | * Following is the early console based on Medfield HSU (High | 245 | * Following is the early console based on Medfield HSU (High |
246 | * Speed UART) device. | 246 | * Speed UART) device. |
247 | */ | 247 | */ |
248 | #define HSU_PORT2_PADDR 0xffa28180 | 248 | #define HSU_PORT_BASE 0xffa28080 |
249 | 249 | ||
250 | static void __iomem *phsu; | 250 | static void __iomem *phsu; |
251 | 251 | ||
252 | void hsu_early_console_init(void) | 252 | void hsu_early_console_init(const char *s) |
253 | { | 253 | { |
254 | unsigned long paddr, port = 0; | ||
254 | u8 lcr; | 255 | u8 lcr; |
255 | 256 | ||
256 | phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, | 257 | /* |
257 | HSU_PORT2_PADDR); | 258 | * Select the early HSU console port if specified by user in the |
259 | * kernel command line. | ||
260 | */ | ||
261 | if (*s && !kstrtoul(s, 10, &port)) | ||
262 | port = clamp_val(port, 0, 2); | ||
263 | |||
264 | paddr = HSU_PORT_BASE + port * 0x80; | ||
265 | phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr); | ||
258 | 266 | ||
259 | /* Disable FIFO */ | 267 | /* Disable FIFO */ |
260 | writeb(0x0, phsu + UART_FCR); | 268 | writeb(0x0, phsu + UART_FCR); |
diff --git a/drivers/parport/parport_ax88796.c b/drivers/parport/parport_ax88796.c index 844f6137970a..7c5d86696eed 100644 --- a/drivers/parport/parport_ax88796.c +++ b/drivers/parport/parport_ax88796.c | |||
@@ -420,18 +420,7 @@ static struct platform_driver axdrv = { | |||
420 | .resume = parport_ax88796_resume, | 420 | .resume = parport_ax88796_resume, |
421 | }; | 421 | }; |
422 | 422 | ||
423 | static int __init parport_ax88796_init(void) | 423 | module_platform_driver(axdrv); |
424 | { | ||
425 | return platform_driver_register(&axdrv); | ||
426 | } | ||
427 | |||
428 | static void __exit parport_ax88796_exit(void) | ||
429 | { | ||
430 | platform_driver_unregister(&axdrv); | ||
431 | } | ||
432 | |||
433 | module_init(parport_ax88796_init) | ||
434 | module_exit(parport_ax88796_exit) | ||
435 | 424 | ||
436 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 425 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
437 | MODULE_DESCRIPTION("AX88796 Parport parallel port driver"); | 426 | MODULE_DESCRIPTION("AX88796 Parport parallel port driver"); |
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 910c5a26e347..9390a534a2b2 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c | |||
@@ -391,21 +391,10 @@ static struct platform_driver bpp_sbus_driver = { | |||
391 | .remove = __devexit_p(bpp_remove), | 391 | .remove = __devexit_p(bpp_remove), |
392 | }; | 392 | }; |
393 | 393 | ||
394 | static int __init parport_sunbpp_init(void) | 394 | module_platform_driver(bpp_sbus_driver); |
395 | { | ||
396 | return platform_driver_register(&bpp_sbus_driver); | ||
397 | } | ||
398 | |||
399 | static void __exit parport_sunbpp_exit(void) | ||
400 | { | ||
401 | platform_driver_unregister(&bpp_sbus_driver); | ||
402 | } | ||
403 | 395 | ||
404 | MODULE_AUTHOR("Derrick J Brashear"); | 396 | MODULE_AUTHOR("Derrick J Brashear"); |
405 | MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); | 397 | MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); |
406 | MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); | 398 | MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); |
407 | MODULE_VERSION("2.0"); | 399 | MODULE_VERSION("2.0"); |
408 | MODULE_LICENSE("GPL"); | 400 | MODULE_LICENSE("GPL"); |
409 | |||
410 | module_init(parport_sunbpp_init) | ||
411 | module_exit(parport_sunbpp_exit) | ||
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index cea56033b34c..a09ce3ef5d74 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c | |||
@@ -417,7 +417,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) | |||
417 | __FILE__,__LINE__,tbuf,tbuf->count); | 417 | __FILE__,__LINE__,tbuf,tbuf->count); |
418 | 418 | ||
419 | /* Send the next block of data to device */ | 419 | /* Send the next block of data to device */ |
420 | tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); | 420 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
421 | actual = tty->ops->write(tty, tbuf->buf, tbuf->count); | 421 | actual = tty->ops->write(tty, tbuf->buf, tbuf->count); |
422 | 422 | ||
423 | /* rollback was possible and has been done */ | 423 | /* rollback was possible and has been done */ |
@@ -459,7 +459,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty) | |||
459 | } | 459 | } |
460 | 460 | ||
461 | if (!tbuf) | 461 | if (!tbuf) |
462 | tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | 462 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
463 | 463 | ||
464 | /* Clear the re-entry flag */ | 464 | /* Clear the re-entry flag */ |
465 | spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); | 465 | spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags); |
@@ -491,7 +491,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) | |||
491 | return; | 491 | return; |
492 | 492 | ||
493 | if (tty != n_hdlc->tty) { | 493 | if (tty != n_hdlc->tty) { |
494 | tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | 494 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
495 | return; | 495 | return; |
496 | } | 496 | } |
497 | 497 | ||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 39d6ab6551e0..d2256d08ee7e 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -61,7 +61,7 @@ | |||
61 | * controlling the space in the read buffer. | 61 | * controlling the space in the read buffer. |
62 | */ | 62 | */ |
63 | #define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */ | 63 | #define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */ |
64 | #define TTY_THRESHOLD_UNTHROTTLE 128 | 64 | #define TTY_THRESHOLD_UNTHROTTLE 128 |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Special byte codes used in the echo buffer to represent operations | 67 | * Special byte codes used in the echo buffer to represent operations |
@@ -405,7 +405,7 @@ static ssize_t process_output_block(struct tty_struct *tty, | |||
405 | const unsigned char *buf, unsigned int nr) | 405 | const unsigned char *buf, unsigned int nr) |
406 | { | 406 | { |
407 | int space; | 407 | int space; |
408 | int i; | 408 | int i; |
409 | const unsigned char *cp; | 409 | const unsigned char *cp; |
410 | 410 | ||
411 | mutex_lock(&tty->output_lock); | 411 | mutex_lock(&tty->output_lock); |
@@ -1607,7 +1607,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
1607 | } | 1607 | } |
1608 | 1608 | ||
1609 | /** | 1609 | /** |
1610 | * copy_from_read_buf - copy read data directly | 1610 | * copy_from_read_buf - copy read data directly |
1611 | * @tty: terminal device | 1611 | * @tty: terminal device |
1612 | * @b: user data | 1612 | * @b: user data |
1613 | * @nr: size of data | 1613 | * @nr: size of data |
@@ -1909,7 +1909,7 @@ do_it_again: | |||
1909 | if (nr) | 1909 | if (nr) |
1910 | clear_bit(TTY_PUSH, &tty->flags); | 1910 | clear_bit(TTY_PUSH, &tty->flags); |
1911 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) | 1911 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) |
1912 | goto do_it_again; | 1912 | goto do_it_again; |
1913 | 1913 | ||
1914 | n_tty_set_room(tty); | 1914 | n_tty_set_room(tty); |
1915 | return retval; | 1915 | return retval; |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index e18604b3fc7d..d8653ab6f498 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -446,19 +446,8 @@ static inline void legacy_pty_init(void) { } | |||
446 | int pty_limit = NR_UNIX98_PTY_DEFAULT; | 446 | int pty_limit = NR_UNIX98_PTY_DEFAULT; |
447 | static int pty_limit_min; | 447 | static int pty_limit_min; |
448 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | 448 | static int pty_limit_max = NR_UNIX98_PTY_MAX; |
449 | static int tty_count; | ||
450 | static int pty_count; | 449 | static int pty_count; |
451 | 450 | ||
452 | static inline void pty_inc_count(void) | ||
453 | { | ||
454 | pty_count = (++tty_count) / 2; | ||
455 | } | ||
456 | |||
457 | static inline void pty_dec_count(void) | ||
458 | { | ||
459 | pty_count = (--tty_count) / 2; | ||
460 | } | ||
461 | |||
462 | static struct cdev ptmx_cdev; | 451 | static struct cdev ptmx_cdev; |
463 | 452 | ||
464 | static struct ctl_table pty_table[] = { | 453 | static struct ctl_table pty_table[] = { |
@@ -600,8 +589,7 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | |||
600 | */ | 589 | */ |
601 | tty_driver_kref_get(driver); | 590 | tty_driver_kref_get(driver); |
602 | tty->count++; | 591 | tty->count++; |
603 | pty_inc_count(); /* tty */ | 592 | pty_count++; |
604 | pty_inc_count(); /* tty->link */ | ||
605 | return 0; | 593 | return 0; |
606 | err_free_mem: | 594 | err_free_mem: |
607 | deinitialize_tty_struct(o_tty); | 595 | deinitialize_tty_struct(o_tty); |
@@ -613,15 +601,19 @@ err_free_tty: | |||
613 | return -ENOMEM; | 601 | return -ENOMEM; |
614 | } | 602 | } |
615 | 603 | ||
616 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | 604 | static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |
605 | { | ||
606 | pty_count--; | ||
607 | } | ||
608 | |||
609 | static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
617 | { | 610 | { |
618 | pty_dec_count(); | ||
619 | } | 611 | } |
620 | 612 | ||
621 | static const struct tty_operations ptm_unix98_ops = { | 613 | static const struct tty_operations ptm_unix98_ops = { |
622 | .lookup = ptm_unix98_lookup, | 614 | .lookup = ptm_unix98_lookup, |
623 | .install = pty_unix98_install, | 615 | .install = pty_unix98_install, |
624 | .remove = pty_unix98_remove, | 616 | .remove = ptm_unix98_remove, |
625 | .open = pty_open, | 617 | .open = pty_open, |
626 | .close = pty_close, | 618 | .close = pty_close, |
627 | .write = pty_write, | 619 | .write = pty_write, |
@@ -638,7 +630,7 @@ static const struct tty_operations ptm_unix98_ops = { | |||
638 | static const struct tty_operations pty_unix98_ops = { | 630 | static const struct tty_operations pty_unix98_ops = { |
639 | .lookup = pts_unix98_lookup, | 631 | .lookup = pts_unix98_lookup, |
640 | .install = pty_unix98_install, | 632 | .install = pty_unix98_install, |
641 | .remove = pty_unix98_remove, | 633 | .remove = pts_unix98_remove, |
642 | .open = pty_open, | 634 | .open = pty_open, |
643 | .close = pty_close, | 635 | .close = pty_close, |
644 | .write = pty_write, | 636 | .write = pty_write, |
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index eeadf1b8e093..9f50c4e3c2be 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c | |||
@@ -129,32 +129,6 @@ static unsigned long probe_rsa[PORT_RSA_MAX]; | |||
129 | static unsigned int probe_rsa_count; | 129 | static unsigned int probe_rsa_count; |
130 | #endif /* CONFIG_SERIAL_8250_RSA */ | 130 | #endif /* CONFIG_SERIAL_8250_RSA */ |
131 | 131 | ||
132 | struct uart_8250_port { | ||
133 | struct uart_port port; | ||
134 | struct timer_list timer; /* "no irq" timer */ | ||
135 | struct list_head list; /* ports on this IRQ */ | ||
136 | unsigned short capabilities; /* port capabilities */ | ||
137 | unsigned short bugs; /* port bugs */ | ||
138 | unsigned int tx_loadsz; /* transmit fifo load size */ | ||
139 | unsigned char acr; | ||
140 | unsigned char ier; | ||
141 | unsigned char lcr; | ||
142 | unsigned char mcr; | ||
143 | unsigned char mcr_mask; /* mask of user bits */ | ||
144 | unsigned char mcr_force; /* mask of forced bits */ | ||
145 | unsigned char cur_iotype; /* Running I/O type */ | ||
146 | |||
147 | /* | ||
148 | * Some bits in registers are cleared on a read, so they must | ||
149 | * be saved whenever the register is read but the bits will not | ||
150 | * be immediately processed. | ||
151 | */ | ||
152 | #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS | ||
153 | unsigned char lsr_saved_flags; | ||
154 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | ||
155 | unsigned char msr_saved_flags; | ||
156 | }; | ||
157 | |||
158 | struct irq_info { | 132 | struct irq_info { |
159 | struct hlist_node node; | 133 | struct hlist_node node; |
160 | int irq; | 134 | int irq; |
@@ -1326,8 +1300,6 @@ static void serial8250_stop_tx(struct uart_port *port) | |||
1326 | } | 1300 | } |
1327 | } | 1301 | } |
1328 | 1302 | ||
1329 | static void transmit_chars(struct uart_8250_port *up); | ||
1330 | |||
1331 | static void serial8250_start_tx(struct uart_port *port) | 1303 | static void serial8250_start_tx(struct uart_port *port) |
1332 | { | 1304 | { |
1333 | struct uart_8250_port *up = | 1305 | struct uart_8250_port *up = |
@@ -1344,7 +1316,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1344 | if ((up->port.type == PORT_RM9000) ? | 1316 | if ((up->port.type == PORT_RM9000) ? |
1345 | (lsr & UART_LSR_THRE) : | 1317 | (lsr & UART_LSR_THRE) : |
1346 | (lsr & UART_LSR_TEMT)) | 1318 | (lsr & UART_LSR_TEMT)) |
1347 | transmit_chars(up); | 1319 | serial8250_tx_chars(up); |
1348 | } | 1320 | } |
1349 | } | 1321 | } |
1350 | 1322 | ||
@@ -1401,11 +1373,16 @@ static void clear_rx_fifo(struct uart_8250_port *up) | |||
1401 | } while (1); | 1373 | } while (1); |
1402 | } | 1374 | } |
1403 | 1375 | ||
1404 | static void | 1376 | /* |
1405 | receive_chars(struct uart_8250_port *up, unsigned int *status) | 1377 | * serial8250_rx_chars: processes according to the passed in LSR |
1378 | * value, and returns the remaining LSR bits not handled | ||
1379 | * by this Rx routine. | ||
1380 | */ | ||
1381 | unsigned char | ||
1382 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | ||
1406 | { | 1383 | { |
1407 | struct tty_struct *tty = up->port.state->port.tty; | 1384 | struct tty_struct *tty = up->port.state->port.tty; |
1408 | unsigned char ch, lsr = *status; | 1385 | unsigned char ch; |
1409 | int max_count = 256; | 1386 | int max_count = 256; |
1410 | char flag; | 1387 | char flag; |
1411 | 1388 | ||
@@ -1481,10 +1458,11 @@ ignore_char: | |||
1481 | spin_unlock(&up->port.lock); | 1458 | spin_unlock(&up->port.lock); |
1482 | tty_flip_buffer_push(tty); | 1459 | tty_flip_buffer_push(tty); |
1483 | spin_lock(&up->port.lock); | 1460 | spin_lock(&up->port.lock); |
1484 | *status = lsr; | 1461 | return lsr; |
1485 | } | 1462 | } |
1463 | EXPORT_SYMBOL_GPL(serial8250_rx_chars); | ||
1486 | 1464 | ||
1487 | static void transmit_chars(struct uart_8250_port *up) | 1465 | void serial8250_tx_chars(struct uart_8250_port *up) |
1488 | { | 1466 | { |
1489 | struct circ_buf *xmit = &up->port.state->xmit; | 1467 | struct circ_buf *xmit = &up->port.state->xmit; |
1490 | int count; | 1468 | int count; |
@@ -1521,8 +1499,9 @@ static void transmit_chars(struct uart_8250_port *up) | |||
1521 | if (uart_circ_empty(xmit)) | 1499 | if (uart_circ_empty(xmit)) |
1522 | __stop_tx(up); | 1500 | __stop_tx(up); |
1523 | } | 1501 | } |
1502 | EXPORT_SYMBOL_GPL(serial8250_tx_chars); | ||
1524 | 1503 | ||
1525 | static unsigned int check_modem_status(struct uart_8250_port *up) | 1504 | unsigned int serial8250_modem_status(struct uart_8250_port *up) |
1526 | { | 1505 | { |
1527 | unsigned int status = serial_in(up, UART_MSR); | 1506 | unsigned int status = serial_in(up, UART_MSR); |
1528 | 1507 | ||
@@ -1544,14 +1523,20 @@ static unsigned int check_modem_status(struct uart_8250_port *up) | |||
1544 | 1523 | ||
1545 | return status; | 1524 | return status; |
1546 | } | 1525 | } |
1526 | EXPORT_SYMBOL_GPL(serial8250_modem_status); | ||
1547 | 1527 | ||
1548 | /* | 1528 | /* |
1549 | * This handles the interrupt from one port. | 1529 | * This handles the interrupt from one port. |
1550 | */ | 1530 | */ |
1551 | static void serial8250_handle_port(struct uart_8250_port *up) | 1531 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir) |
1552 | { | 1532 | { |
1553 | unsigned int status; | 1533 | unsigned char status; |
1554 | unsigned long flags; | 1534 | unsigned long flags; |
1535 | struct uart_8250_port *up = | ||
1536 | container_of(port, struct uart_8250_port, port); | ||
1537 | |||
1538 | if (iir & UART_IIR_NO_INT) | ||
1539 | return 0; | ||
1555 | 1540 | ||
1556 | spin_lock_irqsave(&up->port.lock, flags); | 1541 | spin_lock_irqsave(&up->port.lock, flags); |
1557 | 1542 | ||
@@ -1560,25 +1545,13 @@ static void serial8250_handle_port(struct uart_8250_port *up) | |||
1560 | DEBUG_INTR("status = %x...", status); | 1545 | DEBUG_INTR("status = %x...", status); |
1561 | 1546 | ||
1562 | if (status & (UART_LSR_DR | UART_LSR_BI)) | 1547 | if (status & (UART_LSR_DR | UART_LSR_BI)) |
1563 | receive_chars(up, &status); | 1548 | status = serial8250_rx_chars(up, status); |
1564 | check_modem_status(up); | 1549 | serial8250_modem_status(up); |
1565 | if (status & UART_LSR_THRE) | 1550 | if (status & UART_LSR_THRE) |
1566 | transmit_chars(up); | 1551 | serial8250_tx_chars(up); |
1567 | 1552 | ||
1568 | spin_unlock_irqrestore(&up->port.lock, flags); | 1553 | spin_unlock_irqrestore(&up->port.lock, flags); |
1569 | } | 1554 | return 1; |
1570 | |||
1571 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | ||
1572 | { | ||
1573 | struct uart_8250_port *up = | ||
1574 | container_of(port, struct uart_8250_port, port); | ||
1575 | |||
1576 | if (!(iir & UART_IIR_NO_INT)) { | ||
1577 | serial8250_handle_port(up); | ||
1578 | return 1; | ||
1579 | } | ||
1580 | |||
1581 | return 0; | ||
1582 | } | 1555 | } |
1583 | EXPORT_SYMBOL_GPL(serial8250_handle_irq); | 1556 | EXPORT_SYMBOL_GPL(serial8250_handle_irq); |
1584 | 1557 | ||
@@ -1619,11 +1592,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) | |||
1619 | do { | 1592 | do { |
1620 | struct uart_8250_port *up; | 1593 | struct uart_8250_port *up; |
1621 | struct uart_port *port; | 1594 | struct uart_port *port; |
1595 | bool skip; | ||
1622 | 1596 | ||
1623 | up = list_entry(l, struct uart_8250_port, list); | 1597 | up = list_entry(l, struct uart_8250_port, list); |
1624 | port = &up->port; | 1598 | port = &up->port; |
1599 | skip = pass_counter && up->port.flags & UPF_IIR_ONCE; | ||
1625 | 1600 | ||
1626 | if (port->handle_irq(port)) { | 1601 | if (!skip && port->handle_irq(port)) { |
1627 | handled = 1; | 1602 | handled = 1; |
1628 | end = NULL; | 1603 | end = NULL; |
1629 | } else if (end == NULL) | 1604 | } else if (end == NULL) |
@@ -1758,11 +1733,8 @@ static void serial_unlink_irq_chain(struct uart_8250_port *up) | |||
1758 | static void serial8250_timeout(unsigned long data) | 1733 | static void serial8250_timeout(unsigned long data) |
1759 | { | 1734 | { |
1760 | struct uart_8250_port *up = (struct uart_8250_port *)data; | 1735 | struct uart_8250_port *up = (struct uart_8250_port *)data; |
1761 | unsigned int iir; | ||
1762 | 1736 | ||
1763 | iir = serial_in(up, UART_IIR); | 1737 | up->port.handle_irq(&up->port); |
1764 | if (!(iir & UART_IIR_NO_INT)) | ||
1765 | serial8250_handle_port(up); | ||
1766 | mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port)); | 1738 | mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port)); |
1767 | } | 1739 | } |
1768 | 1740 | ||
@@ -1801,7 +1773,7 @@ static void serial8250_backup_timeout(unsigned long data) | |||
1801 | } | 1773 | } |
1802 | 1774 | ||
1803 | if (!(iir & UART_IIR_NO_INT)) | 1775 | if (!(iir & UART_IIR_NO_INT)) |
1804 | transmit_chars(up); | 1776 | serial8250_tx_chars(up); |
1805 | 1777 | ||
1806 | if (is_real_interrupt(up->port.irq)) | 1778 | if (is_real_interrupt(up->port.irq)) |
1807 | serial_out(up, UART_IER, ier); | 1779 | serial_out(up, UART_IER, ier); |
@@ -1835,7 +1807,7 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) | |||
1835 | unsigned int status; | 1807 | unsigned int status; |
1836 | unsigned int ret; | 1808 | unsigned int ret; |
1837 | 1809 | ||
1838 | status = check_modem_status(up); | 1810 | status = serial8250_modem_status(up); |
1839 | 1811 | ||
1840 | ret = 0; | 1812 | ret = 0; |
1841 | if (status & UART_MSR_DCD) | 1813 | if (status & UART_MSR_DCD) |
@@ -2000,7 +1972,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2000 | serial_outp(up, UART_IER, 0); | 1972 | serial_outp(up, UART_IER, 0); |
2001 | serial_outp(up, UART_LCR, 0); | 1973 | serial_outp(up, UART_LCR, 0); |
2002 | serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ | 1974 | serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ |
2003 | serial_outp(up, UART_LCR, 0xBF); | 1975 | serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B); |
2004 | serial_outp(up, UART_EFR, UART_EFR_ECB); | 1976 | serial_outp(up, UART_EFR, UART_EFR_ECB); |
2005 | serial_outp(up, UART_LCR, 0); | 1977 | serial_outp(up, UART_LCR, 0); |
2006 | } | 1978 | } |
@@ -2848,7 +2820,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2848 | 2820 | ||
2849 | local_irq_save(flags); | 2821 | local_irq_save(flags); |
2850 | if (up->port.sysrq) { | 2822 | if (up->port.sysrq) { |
2851 | /* serial8250_handle_port() already took the lock */ | 2823 | /* serial8250_handle_irq() already took the lock */ |
2852 | locked = 0; | 2824 | locked = 0; |
2853 | } else if (oops_in_progress) { | 2825 | } else if (oops_in_progress) { |
2854 | locked = spin_trylock(&up->port.lock); | 2826 | locked = spin_trylock(&up->port.lock); |
@@ -2882,7 +2854,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2882 | * while processing with interrupts off. | 2854 | * while processing with interrupts off. |
2883 | */ | 2855 | */ |
2884 | if (up->msr_saved_flags) | 2856 | if (up->msr_saved_flags) |
2885 | check_modem_status(up); | 2857 | serial8250_modem_status(up); |
2886 | 2858 | ||
2887 | if (locked) | 2859 | if (locked) |
2888 | spin_unlock(&up->port.lock); | 2860 | spin_unlock(&up->port.lock); |
diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h index 6edf4a6a22d4..ae027be57e25 100644 --- a/drivers/tty/serial/8250.h +++ b/drivers/tty/serial/8250.h | |||
@@ -13,6 +13,32 @@ | |||
13 | 13 | ||
14 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
15 | 15 | ||
16 | struct uart_8250_port { | ||
17 | struct uart_port port; | ||
18 | struct timer_list timer; /* "no irq" timer */ | ||
19 | struct list_head list; /* ports on this IRQ */ | ||
20 | unsigned short capabilities; /* port capabilities */ | ||
21 | unsigned short bugs; /* port bugs */ | ||
22 | unsigned int tx_loadsz; /* transmit fifo load size */ | ||
23 | unsigned char acr; | ||
24 | unsigned char ier; | ||
25 | unsigned char lcr; | ||
26 | unsigned char mcr; | ||
27 | unsigned char mcr_mask; /* mask of user bits */ | ||
28 | unsigned char mcr_force; /* mask of forced bits */ | ||
29 | unsigned char cur_iotype; /* Running I/O type */ | ||
30 | |||
31 | /* | ||
32 | * Some bits in registers are cleared on a read, so they must | ||
33 | * be saved whenever the register is read but the bits will not | ||
34 | * be immediately processed. | ||
35 | */ | ||
36 | #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS | ||
37 | unsigned char lsr_saved_flags; | ||
38 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | ||
39 | unsigned char msr_saved_flags; | ||
40 | }; | ||
41 | |||
16 | struct old_serial_port { | 42 | struct old_serial_port { |
17 | unsigned int uart; | 43 | unsigned int uart; |
18 | unsigned int baud_base; | 44 | unsigned int baud_base; |
diff --git a/drivers/tty/serial/8250_dw.c b/drivers/tty/serial/8250_dw.c index bf1fba640c2d..f574eef3075f 100644 --- a/drivers/tty/serial/8250_dw.c +++ b/drivers/tty/serial/8250_dw.c | |||
@@ -177,17 +177,7 @@ static struct platform_driver dw8250_platform_driver = { | |||
177 | .remove = __devexit_p(dw8250_remove), | 177 | .remove = __devexit_p(dw8250_remove), |
178 | }; | 178 | }; |
179 | 179 | ||
180 | static int __init dw8250_init(void) | 180 | module_platform_driver(dw8250_platform_driver); |
181 | { | ||
182 | return platform_driver_register(&dw8250_platform_driver); | ||
183 | } | ||
184 | module_init(dw8250_init); | ||
185 | |||
186 | static void __exit dw8250_exit(void) | ||
187 | { | ||
188 | platform_driver_unregister(&dw8250_platform_driver); | ||
189 | } | ||
190 | module_exit(dw8250_exit); | ||
191 | 181 | ||
192 | MODULE_AUTHOR("Jamie Iles"); | 182 | MODULE_AUTHOR("Jamie Iles"); |
193 | MODULE_LICENSE("GPL"); | 183 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/tty/serial/8250_fsl.c b/drivers/tty/serial/8250_fsl.c new file mode 100644 index 000000000000..f4d3c47b88e8 --- /dev/null +++ b/drivers/tty/serial/8250_fsl.c | |||
@@ -0,0 +1,63 @@ | |||
1 | #include <linux/serial_reg.h> | ||
2 | #include <linux/serial_8250.h> | ||
3 | |||
4 | #include "8250.h" | ||
5 | |||
6 | /* | ||
7 | * Freescale 16550 UART "driver", Copyright (C) 2011 Paul Gortmaker. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This isn't a full driver; it just provides an alternate IRQ | ||
14 | * handler to deal with an errata. Everything else is just | ||
15 | * using the bog standard 8250 support. | ||
16 | * | ||
17 | * We follow code flow of serial8250_default_handle_irq() but add | ||
18 | * a check for a break and insert a dummy read on the Rx for the | ||
19 | * immediately following IRQ event. | ||
20 | * | ||
21 | * We re-use the already existing "bug handling" lsr_saved_flags | ||
22 | * field to carry the "what we just did" information from the one | ||
23 | * IRQ event to the next one. | ||
24 | */ | ||
25 | |||
26 | int fsl8250_handle_irq(struct uart_port *port) | ||
27 | { | ||
28 | unsigned char lsr, orig_lsr; | ||
29 | unsigned long flags; | ||
30 | unsigned int iir; | ||
31 | struct uart_8250_port *up = | ||
32 | container_of(port, struct uart_8250_port, port); | ||
33 | |||
34 | spin_lock_irqsave(&up->port.lock, flags); | ||
35 | |||
36 | iir = port->serial_in(port, UART_IIR); | ||
37 | if (iir & UART_IIR_NO_INT) { | ||
38 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | /* This is the WAR; if last event was BRK, then read and return */ | ||
43 | if (unlikely(up->lsr_saved_flags & UART_LSR_BI)) { | ||
44 | up->lsr_saved_flags &= ~UART_LSR_BI; | ||
45 | port->serial_in(port, UART_RX); | ||
46 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
47 | return 1; | ||
48 | } | ||
49 | |||
50 | lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR); | ||
51 | |||
52 | if (lsr & (UART_LSR_DR | UART_LSR_BI)) | ||
53 | lsr = serial8250_rx_chars(up, lsr); | ||
54 | |||
55 | serial8250_modem_status(up); | ||
56 | |||
57 | if (lsr & UART_LSR_THRE) | ||
58 | serial8250_tx_chars(up); | ||
59 | |||
60 | up->lsr_saved_flags = orig_lsr; | ||
61 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
62 | return 1; | ||
63 | } | ||
diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 825937a5f210..da2b0b0a183f 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c | |||
@@ -1092,6 +1092,14 @@ static int skip_tx_en_setup(struct serial_private *priv, | |||
1092 | return pci_default_setup(priv, board, port, idx); | 1092 | return pci_default_setup(priv, board, port, idx); |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | static int kt_serial_setup(struct serial_private *priv, | ||
1096 | const struct pciserial_board *board, | ||
1097 | struct uart_port *port, int idx) | ||
1098 | { | ||
1099 | port->flags |= UPF_IIR_ONCE; | ||
1100 | return skip_tx_en_setup(priv, board, port, idx); | ||
1101 | } | ||
1102 | |||
1095 | static int pci_eg20t_init(struct pci_dev *dev) | 1103 | static int pci_eg20t_init(struct pci_dev *dev) |
1096 | { | 1104 | { |
1097 | #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) | 1105 | #if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) |
@@ -1110,7 +1118,18 @@ pci_xr17c154_setup(struct serial_private *priv, | |||
1110 | return pci_default_setup(priv, board, port, idx); | 1118 | return pci_default_setup(priv, board, port, idx); |
1111 | } | 1119 | } |
1112 | 1120 | ||
1113 | /* This should be in linux/pci_ids.h */ | 1121 | static int try_enable_msi(struct pci_dev *dev) |
1122 | { | ||
1123 | /* use msi if available, but fallback to legacy otherwise */ | ||
1124 | pci_enable_msi(dev); | ||
1125 | return 0; | ||
1126 | } | ||
1127 | |||
1128 | static void disable_msi(struct pci_dev *dev) | ||
1129 | { | ||
1130 | pci_disable_msi(dev); | ||
1131 | } | ||
1132 | |||
1114 | #define PCI_VENDOR_ID_SBSMODULARIO 0x124B | 1133 | #define PCI_VENDOR_ID_SBSMODULARIO 0x124B |
1115 | #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B | 1134 | #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B |
1116 | #define PCI_DEVICE_ID_OCTPRO 0x0001 | 1135 | #define PCI_DEVICE_ID_OCTPRO 0x0001 |
@@ -1133,9 +1152,14 @@ pci_xr17c154_setup(struct serial_private *priv, | |||
1133 | #define PCI_DEVICE_ID_TITAN_800E 0xA014 | 1152 | #define PCI_DEVICE_ID_TITAN_800E 0xA014 |
1134 | #define PCI_DEVICE_ID_TITAN_200EI 0xA016 | 1153 | #define PCI_DEVICE_ID_TITAN_200EI 0xA016 |
1135 | #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 | 1154 | #define PCI_DEVICE_ID_TITAN_200EISI 0xA017 |
1155 | #define PCI_DEVICE_ID_TITAN_400V3 0xA310 | ||
1156 | #define PCI_DEVICE_ID_TITAN_410V3 0xA312 | ||
1157 | #define PCI_DEVICE_ID_TITAN_800V3 0xA314 | ||
1158 | #define PCI_DEVICE_ID_TITAN_800V3B 0xA315 | ||
1136 | #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 | 1159 | #define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 |
1137 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 | 1160 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 |
1138 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 | 1161 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 |
1162 | #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d | ||
1139 | 1163 | ||
1140 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1164 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1141 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1165 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -1220,6 +1244,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1220 | .subdevice = PCI_ANY_ID, | 1244 | .subdevice = PCI_ANY_ID, |
1221 | .setup = ce4100_serial_setup, | 1245 | .setup = ce4100_serial_setup, |
1222 | }, | 1246 | }, |
1247 | { | ||
1248 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1249 | .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, | ||
1250 | .subvendor = PCI_ANY_ID, | ||
1251 | .subdevice = PCI_ANY_ID, | ||
1252 | .init = try_enable_msi, | ||
1253 | .setup = kt_serial_setup, | ||
1254 | .exit = disable_msi, | ||
1255 | }, | ||
1223 | /* | 1256 | /* |
1224 | * ITE | 1257 | * ITE |
1225 | */ | 1258 | */ |
@@ -3414,6 +3447,18 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3414 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, | 3447 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200EISI, |
3415 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3448 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3416 | pbn_oxsemi_2_4000000 }, | 3449 | pbn_oxsemi_2_4000000 }, |
3450 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400V3, | ||
3451 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3452 | pbn_b0_4_921600 }, | ||
3453 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_410V3, | ||
3454 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3455 | pbn_b0_4_921600 }, | ||
3456 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3, | ||
3457 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3458 | pbn_b0_4_921600 }, | ||
3459 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800V3B, | ||
3460 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3461 | pbn_b0_4_921600 }, | ||
3417 | 3462 | ||
3418 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, | 3463 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550, |
3419 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3464 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 95b21a619900..113fccf82517 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -97,6 +97,11 @@ config SERIAL_8250_PNP | |||
97 | This builds standard PNP serial support. You may be able to | 97 | This builds standard PNP serial support. You may be able to |
98 | disable this feature if you only need legacy serial support. | 98 | disable this feature if you only need legacy serial support. |
99 | 99 | ||
100 | config SERIAL_8250_FSL | ||
101 | bool | ||
102 | depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 | ||
103 | default PPC | ||
104 | |||
100 | config SERIAL_8250_HP300 | 105 | config SERIAL_8250_HP300 |
101 | tristate | 106 | tristate |
102 | depends on SERIAL_8250 && HP300 | 107 | depends on SERIAL_8250 && HP300 |
@@ -535,6 +540,27 @@ config SERIAL_S5PV210 | |||
535 | help | 540 | help |
536 | Serial port support for Samsung's S5P Family of SoC's | 541 | Serial port support for Samsung's S5P Family of SoC's |
537 | 542 | ||
543 | config SERIAL_SIRFSOC | ||
544 | tristate "SiRF SoC Platform Serial port support" | ||
545 | depends on ARM && ARCH_PRIMA2 | ||
546 | select SERIAL_CORE | ||
547 | help | ||
548 | Support for the on-chip UART on the CSR SiRFprimaII series, | ||
549 | providing /dev/ttySiRF0, 1 and 2 (note, some machines may not | ||
550 | provide all of these ports, depending on how the serial port | ||
551 | pins are configured). | ||
552 | |||
553 | config SERIAL_SIRFSOC_CONSOLE | ||
554 | bool "Support for console on SiRF SoC serial port" | ||
555 | depends on SERIAL_SIRFSOC=y | ||
556 | select SERIAL_CORE_CONSOLE | ||
557 | help | ||
558 | Even if you say Y here, the currently visible virtual console | ||
559 | (/dev/tty0) will still be used as the system console by default, but | ||
560 | you can alter that using a kernel command line option such as | ||
561 | "console=ttySiRFx". (Try "man bootparam" or see the documentation of | ||
562 | your boot loader about how to pass options to the kernel at | ||
563 | boot time.) | ||
538 | 564 | ||
539 | config SERIAL_MAX3100 | 565 | config SERIAL_MAX3100 |
540 | tristate "MAX3100 support" | 566 | tristate "MAX3100 support" |
@@ -1324,7 +1350,7 @@ config SERIAL_OF_PLATFORM | |||
1324 | 1350 | ||
1325 | config SERIAL_OMAP | 1351 | config SERIAL_OMAP |
1326 | tristate "OMAP serial port support" | 1352 | tristate "OMAP serial port support" |
1327 | depends on ARCH_OMAP2 || ARCH_OMAP3 || ARCH_OMAP4 | 1353 | depends on ARCH_OMAP2PLUS |
1328 | select SERIAL_CORE | 1354 | select SERIAL_CORE |
1329 | help | 1355 | help |
1330 | If you have a machine based on an Texas Instruments OMAP CPU you | 1356 | If you have a machine based on an Texas Instruments OMAP CPU you |
@@ -1575,6 +1601,15 @@ config SERIAL_PCH_UART | |||
1575 | ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. | 1601 | ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. |
1576 | ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. | 1602 | ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. |
1577 | 1603 | ||
1604 | config SERIAL_PCH_UART_CONSOLE | ||
1605 | bool "Support for console on Intel EG20T PCH UART/OKI SEMICONDUCTOR ML7213 IOH" | ||
1606 | depends on SERIAL_PCH_UART=y | ||
1607 | select SERIAL_CORE_CONSOLE | ||
1608 | help | ||
1609 | Say Y here if you wish to use the PCH UART as the system console | ||
1610 | (the system console is the device which receives all kernel messages and | ||
1611 | warnings and which allows logins in single user mode). | ||
1612 | |||
1578 | config SERIAL_MSM_SMD | 1613 | config SERIAL_MSM_SMD |
1579 | bool "Enable tty device interface for some SMD ports" | 1614 | bool "Enable tty device interface for some SMD ports" |
1580 | default n | 1615 | default n |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index e10cf5b54b6d..75eadb8d7178 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o | |||
28 | obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o | 28 | obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o |
29 | obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o | 29 | obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o |
30 | obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o | 30 | obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o |
31 | obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o | ||
31 | obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o | 32 | obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o |
32 | obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o | 33 | obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o |
33 | obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o | 34 | obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o |
@@ -94,3 +95,4 @@ obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o | |||
94 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o | 95 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o |
95 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | 96 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o |
96 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | 97 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o |
98 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o | ||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 4c823f341d98..10605ecc99ab 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -212,8 +212,9 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | |||
212 | { | 212 | { |
213 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 213 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
214 | unsigned int mode; | 214 | unsigned int mode; |
215 | unsigned long flags; | ||
215 | 216 | ||
216 | spin_lock(&port->lock); | 217 | spin_lock_irqsave(&port->lock, flags); |
217 | 218 | ||
218 | /* Disable interrupts */ | 219 | /* Disable interrupts */ |
219 | UART_PUT_IDR(port, atmel_port->tx_done_mask); | 220 | UART_PUT_IDR(port, atmel_port->tx_done_mask); |
@@ -244,7 +245,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) | |||
244 | /* Enable interrupts */ | 245 | /* Enable interrupts */ |
245 | UART_PUT_IER(port, atmel_port->tx_done_mask); | 246 | UART_PUT_IER(port, atmel_port->tx_done_mask); |
246 | 247 | ||
247 | spin_unlock(&port->lock); | 248 | spin_unlock_irqrestore(&port->lock, flags); |
248 | 249 | ||
249 | } | 250 | } |
250 | 251 | ||
@@ -1256,12 +1257,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1256 | 1257 | ||
1257 | static void atmel_set_ldisc(struct uart_port *port, int new) | 1258 | static void atmel_set_ldisc(struct uart_port *port, int new) |
1258 | { | 1259 | { |
1259 | int line = port->line; | 1260 | if (new == N_PPS) { |
1260 | |||
1261 | if (line >= port->state->port.tty->driver->num) | ||
1262 | return; | ||
1263 | |||
1264 | if (port->state->port.tty->ldisc->ops->num == N_PPS) { | ||
1265 | port->flags |= UPF_HARDPPS_CD; | 1261 | port->flags |= UPF_HARDPPS_CD; |
1266 | atmel_enable_ms(port); | 1262 | atmel_enable_ms(port); |
1267 | } else { | 1263 | } else { |
diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index ee101c0d358f..7fbc3a08f10d 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c | |||
@@ -299,8 +299,13 @@ static int sport_startup(struct uart_port *port) | |||
299 | dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n"); | 299 | dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n"); |
300 | } | 300 | } |
301 | } | 301 | } |
302 | if (up->rts_pin >= 0) | 302 | if (up->rts_pin >= 0) { |
303 | gpio_direction_output(up->rts_pin, 0); | 303 | if (gpio_request(up->rts_pin, DRV_NAME)) { |
304 | dev_info(port->dev, "fail to request RTS PIN at GPIO_%d\n", up->rts_pin); | ||
305 | up->rts_pin = -1; | ||
306 | } else | ||
307 | gpio_direction_output(up->rts_pin, 0); | ||
308 | } | ||
304 | #endif | 309 | #endif |
305 | 310 | ||
306 | return 0; | 311 | return 0; |
@@ -445,6 +450,8 @@ static void sport_shutdown(struct uart_port *port) | |||
445 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS | 450 | #ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS |
446 | if (up->cts_pin >= 0) | 451 | if (up->cts_pin >= 0) |
447 | free_irq(gpio_to_irq(up->cts_pin), up); | 452 | free_irq(gpio_to_irq(up->cts_pin), up); |
453 | if (up->rts_pin >= 0) | ||
454 | gpio_free(up->rts_pin); | ||
448 | #endif | 455 | #endif |
449 | } | 456 | } |
450 | 457 | ||
@@ -803,17 +810,16 @@ static int __devinit sport_uart_probe(struct platform_device *pdev) | |||
803 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 810 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
804 | if (res == NULL) | 811 | if (res == NULL) |
805 | sport->cts_pin = -1; | 812 | sport->cts_pin = -1; |
806 | else | 813 | else { |
807 | sport->cts_pin = res->start; | 814 | sport->cts_pin = res->start; |
815 | sport->port.flags |= ASYNC_CTS_FLOW; | ||
816 | } | ||
808 | 817 | ||
809 | res = platform_get_resource(pdev, IORESOURCE_IO, 1); | 818 | res = platform_get_resource(pdev, IORESOURCE_IO, 1); |
810 | if (res == NULL) | 819 | if (res == NULL) |
811 | sport->rts_pin = -1; | 820 | sport->rts_pin = -1; |
812 | else | 821 | else |
813 | sport->rts_pin = res->start; | 822 | sport->rts_pin = res->start; |
814 | |||
815 | if (sport->rts_pin >= 0) | ||
816 | gpio_request(sport->rts_pin, DRV_NAME); | ||
817 | #endif | 823 | #endif |
818 | } | 824 | } |
819 | 825 | ||
@@ -853,10 +859,6 @@ static int __devexit sport_uart_remove(struct platform_device *pdev) | |||
853 | 859 | ||
854 | if (sport) { | 860 | if (sport) { |
855 | uart_remove_one_port(&sport_uart_reg, &sport->port); | 861 | uart_remove_one_port(&sport_uart_reg, &sport->port); |
856 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
857 | if (sport->rts_pin >= 0) | ||
858 | gpio_free(sport->rts_pin); | ||
859 | #endif | ||
860 | iounmap(sport->port.membase); | 862 | iounmap(sport->port.membase); |
861 | peripheral_free_list( | 863 | peripheral_free_list( |
862 | (unsigned short *)pdev->dev.platform_data); | 864 | (unsigned short *)pdev->dev.platform_data); |
diff --git a/drivers/tty/serial/bfin_sport_uart.h b/drivers/tty/serial/bfin_sport_uart.h index 6d06ce1d5675..e4510ea135ce 100644 --- a/drivers/tty/serial/bfin_sport_uart.h +++ b/drivers/tty/serial/bfin_sport_uart.h | |||
@@ -45,11 +45,12 @@ | |||
45 | #define SPORT_GET_RX32(sport) \ | 45 | #define SPORT_GET_RX32(sport) \ |
46 | ({ \ | 46 | ({ \ |
47 | unsigned int __ret; \ | 47 | unsigned int __ret; \ |
48 | unsigned long flags; \ | ||
48 | if (ANOMALY_05000473) \ | 49 | if (ANOMALY_05000473) \ |
49 | local_irq_disable(); \ | 50 | local_irq_save(flags); \ |
50 | __ret = bfin_read32((sport)->port.membase + OFFSET_RX); \ | 51 | __ret = bfin_read32((sport)->port.membase + OFFSET_RX); \ |
51 | if (ANOMALY_05000473) \ | 52 | if (ANOMALY_05000473) \ |
52 | local_irq_enable(); \ | 53 | local_irq_restore(flags); \ |
53 | __ret; \ | 54 | __ret; \ |
54 | }) | 55 | }) |
55 | #define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1)) | 56 | #define SPORT_GET_RCR1(sport) bfin_read16(((sport)->port.membase + OFFSET_RCR1)) |
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 66afb98b77b5..26953bfa6922 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -116,15 +116,22 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
116 | static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) | 116 | static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) |
117 | { | 117 | { |
118 | struct bfin_serial_port *uart = dev_id; | 118 | struct bfin_serial_port *uart = dev_id; |
119 | unsigned int status; | 119 | unsigned int status = bfin_serial_get_mctrl(&uart->port); |
120 | |||
121 | status = bfin_serial_get_mctrl(&uart->port); | ||
122 | uart_handle_cts_change(&uart->port, status & TIOCM_CTS); | ||
123 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 120 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
124 | uart->scts = 1; | 121 | struct tty_struct *tty = uart->port.state->port.tty; |
122 | |||
125 | UART_CLEAR_SCTS(uart); | 123 | UART_CLEAR_SCTS(uart); |
126 | UART_CLEAR_IER(uart, EDSSI); | 124 | if (tty->hw_stopped) { |
125 | if (status) { | ||
126 | tty->hw_stopped = 0; | ||
127 | uart_write_wakeup(&uart->port); | ||
128 | } | ||
129 | } else { | ||
130 | if (!status) | ||
131 | tty->hw_stopped = 1; | ||
132 | } | ||
127 | #endif | 133 | #endif |
134 | uart_handle_cts_change(&uart->port, status & TIOCM_CTS); | ||
128 | 135 | ||
129 | return IRQ_HANDLED; | 136 | return IRQ_HANDLED; |
130 | } | 137 | } |
@@ -175,13 +182,6 @@ static void bfin_serial_start_tx(struct uart_port *port) | |||
175 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; | 182 | struct bfin_serial_port *uart = (struct bfin_serial_port *)port; |
176 | struct tty_struct *tty = uart->port.state->port.tty; | 183 | struct tty_struct *tty = uart->port.state->port.tty; |
177 | 184 | ||
178 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
179 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { | ||
180 | uart->scts = 0; | ||
181 | uart_handle_cts_change(&uart->port, uart->scts); | ||
182 | } | ||
183 | #endif | ||
184 | |||
185 | /* | 185 | /* |
186 | * To avoid losting RX interrupt, we reset IR function | 186 | * To avoid losting RX interrupt, we reset IR function |
187 | * before sending data. | 187 | * before sending data. |
@@ -380,12 +380,6 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) | |||
380 | { | 380 | { |
381 | struct bfin_serial_port *uart = dev_id; | 381 | struct bfin_serial_port *uart = dev_id; |
382 | 382 | ||
383 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
384 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) { | ||
385 | uart->scts = 0; | ||
386 | uart_handle_cts_change(&uart->port, uart->scts); | ||
387 | } | ||
388 | #endif | ||
389 | spin_lock(&uart->port.lock); | 383 | spin_lock(&uart->port.lock); |
390 | if (UART_GET_LSR(uart) & THRE) | 384 | if (UART_GET_LSR(uart) & THRE) |
391 | bfin_serial_tx_chars(uart); | 385 | bfin_serial_tx_chars(uart); |
@@ -531,13 +525,6 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) | |||
531 | struct bfin_serial_port *uart = dev_id; | 525 | struct bfin_serial_port *uart = dev_id; |
532 | struct circ_buf *xmit = &uart->port.state->xmit; | 526 | struct circ_buf *xmit = &uart->port.state->xmit; |
533 | 527 | ||
534 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | ||
535 | if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) { | ||
536 | uart->scts = 0; | ||
537 | uart_handle_cts_change(&uart->port, uart->scts); | ||
538 | } | ||
539 | #endif | ||
540 | |||
541 | spin_lock(&uart->port.lock); | 528 | spin_lock(&uart->port.lock); |
542 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { | 529 | if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { |
543 | disable_dma(uart->tx_dma_channel); | 530 | disable_dma(uart->tx_dma_channel); |
@@ -739,20 +726,26 @@ static int bfin_serial_startup(struct uart_port *port) | |||
739 | pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); | 726 | pr_info("Unable to attach BlackFin UART CTS interrupt. So, disable it.\n"); |
740 | } | 727 | } |
741 | } | 728 | } |
742 | if (uart->rts_pin >= 0) | 729 | if (uart->rts_pin >= 0) { |
743 | gpio_direction_output(uart->rts_pin, 0); | 730 | if (gpio_request(uart->rts_pin, DRIVER_NAME)) { |
731 | pr_info("fail to request RTS PIN at GPIO_%d\n", uart->rts_pin); | ||
732 | uart->rts_pin = -1; | ||
733 | } else | ||
734 | gpio_direction_output(uart->rts_pin, 0); | ||
735 | } | ||
744 | #endif | 736 | #endif |
745 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 737 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
746 | if (uart->cts_pin >= 0 && request_irq(uart->status_irq, | 738 | if (uart->cts_pin >= 0) { |
747 | bfin_serial_mctrl_cts_int, | 739 | if (request_irq(uart->status_irq, bfin_serial_mctrl_cts_int, |
748 | 0, "BFIN_UART_MODEM_STATUS", uart)) { | 740 | IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) { |
749 | uart->cts_pin = -1; | 741 | uart->cts_pin = -1; |
750 | pr_info("Unable to attach BlackFin UART Modem Status interrupt.\n"); | 742 | dev_info(port->dev, "Unable to attach BlackFin UART Modem Status interrupt.\n"); |
751 | } | 743 | } |
752 | 744 | ||
753 | /* CTS RTS PINs are negative assertive. */ | 745 | /* CTS RTS PINs are negative assertive. */ |
754 | UART_PUT_MCR(uart, ACTS); | 746 | UART_PUT_MCR(uart, ACTS); |
755 | UART_SET_IER(uart, EDSSI); | 747 | UART_SET_IER(uart, EDSSI); |
748 | } | ||
756 | #endif | 749 | #endif |
757 | 750 | ||
758 | UART_SET_IER(uart, ERBFI); | 751 | UART_SET_IER(uart, ERBFI); |
@@ -792,6 +785,8 @@ static void bfin_serial_shutdown(struct uart_port *port) | |||
792 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | 785 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS |
793 | if (uart->cts_pin >= 0) | 786 | if (uart->cts_pin >= 0) |
794 | free_irq(gpio_to_irq(uart->cts_pin), uart); | 787 | free_irq(gpio_to_irq(uart->cts_pin), uart); |
788 | if (uart->rts_pin >= 0) | ||
789 | gpio_free(uart->rts_pin); | ||
795 | #endif | 790 | #endif |
796 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 791 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
797 | if (uart->cts_pin >= 0) | 792 | if (uart->cts_pin >= 0) |
@@ -1370,18 +1365,18 @@ static int bfin_serial_probe(struct platform_device *pdev) | |||
1370 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1365 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1371 | if (res == NULL) | 1366 | if (res == NULL) |
1372 | uart->cts_pin = -1; | 1367 | uart->cts_pin = -1; |
1373 | else | 1368 | else { |
1374 | uart->cts_pin = res->start; | 1369 | uart->cts_pin = res->start; |
1370 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
1371 | uart->port.flags |= ASYNC_CTS_FLOW; | ||
1372 | #endif | ||
1373 | } | ||
1375 | 1374 | ||
1376 | res = platform_get_resource(pdev, IORESOURCE_IO, 1); | 1375 | res = platform_get_resource(pdev, IORESOURCE_IO, 1); |
1377 | if (res == NULL) | 1376 | if (res == NULL) |
1378 | uart->rts_pin = -1; | 1377 | uart->rts_pin = -1; |
1379 | else | 1378 | else |
1380 | uart->rts_pin = res->start; | 1379 | uart->rts_pin = res->start; |
1381 | # if defined(CONFIG_SERIAL_BFIN_CTSRTS) | ||
1382 | if (uart->rts_pin >= 0) | ||
1383 | gpio_request(uart->rts_pin, DRIVER_NAME); | ||
1384 | # endif | ||
1385 | #endif | 1380 | #endif |
1386 | } | 1381 | } |
1387 | 1382 | ||
@@ -1421,10 +1416,6 @@ static int __devexit bfin_serial_remove(struct platform_device *pdev) | |||
1421 | 1416 | ||
1422 | if (uart) { | 1417 | if (uart) { |
1423 | uart_remove_one_port(&bfin_serial_reg, &uart->port); | 1418 | uart_remove_one_port(&bfin_serial_reg, &uart->port); |
1424 | #ifdef CONFIG_SERIAL_BFIN_CTSRTS | ||
1425 | if (uart->rts_pin >= 0) | ||
1426 | gpio_free(uart->rts_pin); | ||
1427 | #endif | ||
1428 | iounmap(uart->port.membase); | 1419 | iounmap(uart->port.membase); |
1429 | peripheral_free_list( | 1420 | peripheral_free_list( |
1430 | (unsigned short *)pdev->dev.platform_data); | 1421 | (unsigned short *)pdev->dev.platform_data); |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 426434e5eb7c..7e925e20cbaa 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -1334,7 +1334,6 @@ MODULE_DEVICE_TABLE(spi, ifx_id_table); | |||
1334 | static const struct spi_driver ifx_spi_driver = { | 1334 | static const struct spi_driver ifx_spi_driver = { |
1335 | .driver = { | 1335 | .driver = { |
1336 | .name = DRVNAME, | 1336 | .name = DRVNAME, |
1337 | .bus = &spi_bus_type, | ||
1338 | .pm = &ifx_spi_pm, | 1337 | .pm = &ifx_spi_pm, |
1339 | .owner = THIS_MODULE}, | 1338 | .owner = THIS_MODULE}, |
1340 | .probe = ifx_spi_spi_probe, | 1339 | .probe = ifx_spi_spi_probe, |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 163fc9021f5a..0b7fed746b27 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -102,6 +102,7 @@ | |||
102 | #define UCR2_STPB (1<<6) /* Stop */ | 102 | #define UCR2_STPB (1<<6) /* Stop */ |
103 | #define UCR2_WS (1<<5) /* Word size */ | 103 | #define UCR2_WS (1<<5) /* Word size */ |
104 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ | 104 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ |
105 | #define UCR2_ATEN (1<<3) /* Aging Timer Enable */ | ||
105 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ | 106 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ |
106 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ | 107 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ |
107 | #define UCR2_SRST (1<<0) /* SW reset */ | 108 | #define UCR2_SRST (1<<0) /* SW reset */ |
@@ -207,6 +208,12 @@ struct imx_port { | |||
207 | struct imx_uart_data *devdata; | 208 | struct imx_uart_data *devdata; |
208 | }; | 209 | }; |
209 | 210 | ||
211 | struct imx_port_ucrs { | ||
212 | unsigned int ucr1; | ||
213 | unsigned int ucr2; | ||
214 | unsigned int ucr3; | ||
215 | }; | ||
216 | |||
210 | #ifdef CONFIG_IRDA | 217 | #ifdef CONFIG_IRDA |
211 | #define USE_IRDA(sport) ((sport)->use_irda) | 218 | #define USE_IRDA(sport) ((sport)->use_irda) |
212 | #else | 219 | #else |
@@ -260,6 +267,27 @@ static inline int is_imx21_uart(struct imx_port *sport) | |||
260 | } | 267 | } |
261 | 268 | ||
262 | /* | 269 | /* |
270 | * Save and restore functions for UCR1, UCR2 and UCR3 registers | ||
271 | */ | ||
272 | static void imx_port_ucrs_save(struct uart_port *port, | ||
273 | struct imx_port_ucrs *ucr) | ||
274 | { | ||
275 | /* save control registers */ | ||
276 | ucr->ucr1 = readl(port->membase + UCR1); | ||
277 | ucr->ucr2 = readl(port->membase + UCR2); | ||
278 | ucr->ucr3 = readl(port->membase + UCR3); | ||
279 | } | ||
280 | |||
281 | static void imx_port_ucrs_restore(struct uart_port *port, | ||
282 | struct imx_port_ucrs *ucr) | ||
283 | { | ||
284 | /* restore control registers */ | ||
285 | writel(ucr->ucr1, port->membase + UCR1); | ||
286 | writel(ucr->ucr2, port->membase + UCR2); | ||
287 | writel(ucr->ucr3, port->membase + UCR3); | ||
288 | } | ||
289 | |||
290 | /* | ||
263 | * Handle any change of modem status signal since we were last called. | 291 | * Handle any change of modem status signal since we were last called. |
264 | */ | 292 | */ |
265 | static void imx_mctrl_check(struct imx_port *sport) | 293 | static void imx_mctrl_check(struct imx_port *sport) |
@@ -566,6 +594,9 @@ static irqreturn_t imx_int(int irq, void *dev_id) | |||
566 | if (sts & USR1_RTSD) | 594 | if (sts & USR1_RTSD) |
567 | imx_rtsint(irq, dev_id); | 595 | imx_rtsint(irq, dev_id); |
568 | 596 | ||
597 | if (sts & USR1_AWAKE) | ||
598 | writel(USR1_AWAKE, sport->port.membase + USR1); | ||
599 | |||
569 | return IRQ_HANDLED; | 600 | return IRQ_HANDLED; |
570 | } | 601 | } |
571 | 602 | ||
@@ -901,6 +932,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
901 | ucr2 |= UCR2_PROE; | 932 | ucr2 |= UCR2_PROE; |
902 | } | 933 | } |
903 | 934 | ||
935 | del_timer_sync(&sport->timer); | ||
936 | |||
904 | /* | 937 | /* |
905 | * Ask the core to calculate the divisor for us. | 938 | * Ask the core to calculate the divisor for us. |
906 | */ | 939 | */ |
@@ -931,8 +964,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
931 | sport->port.ignore_status_mask |= URXD_OVRRUN; | 964 | sport->port.ignore_status_mask |= URXD_OVRRUN; |
932 | } | 965 | } |
933 | 966 | ||
934 | del_timer_sync(&sport->timer); | ||
935 | |||
936 | /* | 967 | /* |
937 | * Update the per-port timeout. | 968 | * Update the per-port timeout. |
938 | */ | 969 | */ |
@@ -1079,6 +1110,70 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1079 | return ret; | 1110 | return ret; |
1080 | } | 1111 | } |
1081 | 1112 | ||
1113 | #if defined(CONFIG_CONSOLE_POLL) | ||
1114 | static int imx_poll_get_char(struct uart_port *port) | ||
1115 | { | ||
1116 | struct imx_port_ucrs old_ucr; | ||
1117 | unsigned int status; | ||
1118 | unsigned char c; | ||
1119 | |||
1120 | /* save control registers */ | ||
1121 | imx_port_ucrs_save(port, &old_ucr); | ||
1122 | |||
1123 | /* disable interrupts */ | ||
1124 | writel(UCR1_UARTEN, port->membase + UCR1); | ||
1125 | writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI), | ||
1126 | port->membase + UCR2); | ||
1127 | writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN), | ||
1128 | port->membase + UCR3); | ||
1129 | |||
1130 | /* poll */ | ||
1131 | do { | ||
1132 | status = readl(port->membase + USR2); | ||
1133 | } while (~status & USR2_RDR); | ||
1134 | |||
1135 | /* read */ | ||
1136 | c = readl(port->membase + URXD0); | ||
1137 | |||
1138 | /* restore control registers */ | ||
1139 | imx_port_ucrs_restore(port, &old_ucr); | ||
1140 | |||
1141 | return c; | ||
1142 | } | ||
1143 | |||
1144 | static void imx_poll_put_char(struct uart_port *port, unsigned char c) | ||
1145 | { | ||
1146 | struct imx_port_ucrs old_ucr; | ||
1147 | unsigned int status; | ||
1148 | |||
1149 | /* save control registers */ | ||
1150 | imx_port_ucrs_save(port, &old_ucr); | ||
1151 | |||
1152 | /* disable interrupts */ | ||
1153 | writel(UCR1_UARTEN, port->membase + UCR1); | ||
1154 | writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI), | ||
1155 | port->membase + UCR2); | ||
1156 | writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN), | ||
1157 | port->membase + UCR3); | ||
1158 | |||
1159 | /* drain */ | ||
1160 | do { | ||
1161 | status = readl(port->membase + USR1); | ||
1162 | } while (~status & USR1_TRDY); | ||
1163 | |||
1164 | /* write */ | ||
1165 | writel(c, port->membase + URTX0); | ||
1166 | |||
1167 | /* flush */ | ||
1168 | do { | ||
1169 | status = readl(port->membase + USR2); | ||
1170 | } while (~status & USR2_TXDC); | ||
1171 | |||
1172 | /* restore control registers */ | ||
1173 | imx_port_ucrs_restore(port, &old_ucr); | ||
1174 | } | ||
1175 | #endif | ||
1176 | |||
1082 | static struct uart_ops imx_pops = { | 1177 | static struct uart_ops imx_pops = { |
1083 | .tx_empty = imx_tx_empty, | 1178 | .tx_empty = imx_tx_empty, |
1084 | .set_mctrl = imx_set_mctrl, | 1179 | .set_mctrl = imx_set_mctrl, |
@@ -1096,6 +1191,10 @@ static struct uart_ops imx_pops = { | |||
1096 | .request_port = imx_request_port, | 1191 | .request_port = imx_request_port, |
1097 | .config_port = imx_config_port, | 1192 | .config_port = imx_config_port, |
1098 | .verify_port = imx_verify_port, | 1193 | .verify_port = imx_verify_port, |
1194 | #if defined(CONFIG_CONSOLE_POLL) | ||
1195 | .poll_get_char = imx_poll_get_char, | ||
1196 | .poll_put_char = imx_poll_put_char, | ||
1197 | #endif | ||
1099 | }; | 1198 | }; |
1100 | 1199 | ||
1101 | static struct imx_port *imx_ports[UART_NR]; | 1200 | static struct imx_port *imx_ports[UART_NR]; |
@@ -1118,13 +1217,14 @@ static void | |||
1118 | imx_console_write(struct console *co, const char *s, unsigned int count) | 1217 | imx_console_write(struct console *co, const char *s, unsigned int count) |
1119 | { | 1218 | { |
1120 | struct imx_port *sport = imx_ports[co->index]; | 1219 | struct imx_port *sport = imx_ports[co->index]; |
1121 | unsigned int old_ucr1, old_ucr2, ucr1; | 1220 | struct imx_port_ucrs old_ucr; |
1221 | unsigned int ucr1; | ||
1122 | 1222 | ||
1123 | /* | 1223 | /* |
1124 | * First, save UCR1/2 and then disable interrupts | 1224 | * First, save UCR1/2/3 and then disable interrupts |
1125 | */ | 1225 | */ |
1126 | ucr1 = old_ucr1 = readl(sport->port.membase + UCR1); | 1226 | imx_port_ucrs_save(&sport->port, &old_ucr); |
1127 | old_ucr2 = readl(sport->port.membase + UCR2); | 1227 | ucr1 = old_ucr.ucr1; |
1128 | 1228 | ||
1129 | if (is_imx1_uart(sport)) | 1229 | if (is_imx1_uart(sport)) |
1130 | ucr1 |= IMX1_UCR1_UARTCLKEN; | 1230 | ucr1 |= IMX1_UCR1_UARTCLKEN; |
@@ -1133,18 +1233,17 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1133 | 1233 | ||
1134 | writel(ucr1, sport->port.membase + UCR1); | 1234 | writel(ucr1, sport->port.membase + UCR1); |
1135 | 1235 | ||
1136 | writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2); | 1236 | writel(old_ucr.ucr2 | UCR2_TXEN, sport->port.membase + UCR2); |
1137 | 1237 | ||
1138 | uart_console_write(&sport->port, s, count, imx_console_putchar); | 1238 | uart_console_write(&sport->port, s, count, imx_console_putchar); |
1139 | 1239 | ||
1140 | /* | 1240 | /* |
1141 | * Finally, wait for transmitter to become empty | 1241 | * Finally, wait for transmitter to become empty |
1142 | * and restore UCR1/2 | 1242 | * and restore UCR1/2/3 |
1143 | */ | 1243 | */ |
1144 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); | 1244 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); |
1145 | 1245 | ||
1146 | writel(old_ucr1, sport->port.membase + UCR1); | 1246 | imx_port_ucrs_restore(&sport->port, &old_ucr); |
1147 | writel(old_ucr2, sport->port.membase + UCR2); | ||
1148 | } | 1247 | } |
1149 | 1248 | ||
1150 | /* | 1249 | /* |
@@ -1269,6 +1368,12 @@ static struct uart_driver imx_reg = { | |||
1269 | static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) | 1368 | static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) |
1270 | { | 1369 | { |
1271 | struct imx_port *sport = platform_get_drvdata(dev); | 1370 | struct imx_port *sport = platform_get_drvdata(dev); |
1371 | unsigned int val; | ||
1372 | |||
1373 | /* enable wakeup from i.MX UART */ | ||
1374 | val = readl(sport->port.membase + UCR3); | ||
1375 | val |= UCR3_AWAKEN; | ||
1376 | writel(val, sport->port.membase + UCR3); | ||
1272 | 1377 | ||
1273 | if (sport) | 1378 | if (sport) |
1274 | uart_suspend_port(&imx_reg, &sport->port); | 1379 | uart_suspend_port(&imx_reg, &sport->port); |
@@ -1279,6 +1384,12 @@ static int serial_imx_suspend(struct platform_device *dev, pm_message_t state) | |||
1279 | static int serial_imx_resume(struct platform_device *dev) | 1384 | static int serial_imx_resume(struct platform_device *dev) |
1280 | { | 1385 | { |
1281 | struct imx_port *sport = platform_get_drvdata(dev); | 1386 | struct imx_port *sport = platform_get_drvdata(dev); |
1387 | unsigned int val; | ||
1388 | |||
1389 | /* disable wakeup from i.MX UART */ | ||
1390 | val = readl(sport->port.membase + UCR3); | ||
1391 | val &= ~UCR3_AWAKEN; | ||
1392 | writel(val, sport->port.membase + UCR3); | ||
1282 | 1393 | ||
1283 | if (sport) | 1394 | if (sport) |
1284 | uart_resume_port(&imx_reg, &sport->port); | 1395 | uart_resume_port(&imx_reg, &sport->port); |
@@ -1287,6 +1398,10 @@ static int serial_imx_resume(struct platform_device *dev) | |||
1287 | } | 1398 | } |
1288 | 1399 | ||
1289 | #ifdef CONFIG_OF | 1400 | #ifdef CONFIG_OF |
1401 | /* | ||
1402 | * This function returns 1 iff pdev isn't a device instatiated by dt, 0 iff it | ||
1403 | * could successfully get all information from dt or a negative errno. | ||
1404 | */ | ||
1290 | static int serial_imx_probe_dt(struct imx_port *sport, | 1405 | static int serial_imx_probe_dt(struct imx_port *sport, |
1291 | struct platform_device *pdev) | 1406 | struct platform_device *pdev) |
1292 | { | 1407 | { |
@@ -1296,12 +1411,13 @@ static int serial_imx_probe_dt(struct imx_port *sport, | |||
1296 | int ret; | 1411 | int ret; |
1297 | 1412 | ||
1298 | if (!np) | 1413 | if (!np) |
1299 | return -ENODEV; | 1414 | /* no device tree device */ |
1415 | return 1; | ||
1300 | 1416 | ||
1301 | ret = of_alias_get_id(np, "serial"); | 1417 | ret = of_alias_get_id(np, "serial"); |
1302 | if (ret < 0) { | 1418 | if (ret < 0) { |
1303 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); | 1419 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); |
1304 | return -ENODEV; | 1420 | return ret; |
1305 | } | 1421 | } |
1306 | sport->port.line = ret; | 1422 | sport->port.line = ret; |
1307 | 1423 | ||
@@ -1319,7 +1435,7 @@ static int serial_imx_probe_dt(struct imx_port *sport, | |||
1319 | static inline int serial_imx_probe_dt(struct imx_port *sport, | 1435 | static inline int serial_imx_probe_dt(struct imx_port *sport, |
1320 | struct platform_device *pdev) | 1436 | struct platform_device *pdev) |
1321 | { | 1437 | { |
1322 | return -ENODEV; | 1438 | return 1; |
1323 | } | 1439 | } |
1324 | #endif | 1440 | #endif |
1325 | 1441 | ||
@@ -1354,8 +1470,10 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1354 | return -ENOMEM; | 1470 | return -ENOMEM; |
1355 | 1471 | ||
1356 | ret = serial_imx_probe_dt(sport, pdev); | 1472 | ret = serial_imx_probe_dt(sport, pdev); |
1357 | if (ret == -ENODEV) | 1473 | if (ret > 0) |
1358 | serial_imx_probe_pdata(sport, pdev); | 1474 | serial_imx_probe_pdata(sport, pdev); |
1475 | else if (ret < 0) | ||
1476 | goto free; | ||
1359 | 1477 | ||
1360 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1478 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1361 | if (!res) { | 1479 | if (!res) { |
@@ -1476,7 +1594,7 @@ static int __init imx_serial_init(void) | |||
1476 | if (ret != 0) | 1594 | if (ret != 0) |
1477 | uart_unregister_driver(&imx_reg); | 1595 | uart_unregister_driver(&imx_reg); |
1478 | 1596 | ||
1479 | return 0; | 1597 | return ret; |
1480 | } | 1598 | } |
1481 | 1599 | ||
1482 | static void __exit imx_serial_exit(void) | 1600 | static void __exit imx_serial_exit(void) |
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 08018934e013..94a6792bf97b 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
@@ -1000,11 +1000,8 @@ static void __init m32r_sio_register_ports(struct uart_driver *drv) | |||
1000 | init_timer(&up->timer); | 1000 | init_timer(&up->timer); |
1001 | up->timer.function = m32r_sio_timeout; | 1001 | up->timer.function = m32r_sio_timeout; |
1002 | 1002 | ||
1003 | /* | 1003 | up->mcr_mask = ~0; |
1004 | * ALPHA_KLUDGE_MCR needs to be killed. | 1004 | up->mcr_force = 0; |
1005 | */ | ||
1006 | up->mcr_mask = ~ALPHA_KLUDGE_MCR; | ||
1007 | up->mcr_force = ALPHA_KLUDGE_MCR; | ||
1008 | 1005 | ||
1009 | uart_add_one_port(drv, &up->port); | 1006 | uart_add_one_port(drv, &up->port); |
1010 | } | 1007 | } |
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 8a6cc8c30b5a..b4902b99cfd2 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
@@ -901,7 +901,6 @@ static int max3100_resume(struct spi_device *spi) | |||
901 | static struct spi_driver max3100_driver = { | 901 | static struct spi_driver max3100_driver = { |
902 | .driver = { | 902 | .driver = { |
903 | .name = "max3100", | 903 | .name = "max3100", |
904 | .bus = &spi_bus_type, | ||
905 | .owner = THIS_MODULE, | 904 | .owner = THIS_MODULE, |
906 | }, | 905 | }, |
907 | 906 | ||
diff --git a/drivers/tty/serial/max3107-aava.c b/drivers/tty/serial/max3107-aava.c index 90c40f22ec70..aae772a71de6 100644 --- a/drivers/tty/serial/max3107-aava.c +++ b/drivers/tty/serial/max3107-aava.c | |||
@@ -315,7 +315,6 @@ static int __devinit max3107_probe_aava(struct spi_device *spi) | |||
315 | static struct spi_driver max3107_driver = { | 315 | static struct spi_driver max3107_driver = { |
316 | .driver = { | 316 | .driver = { |
317 | .name = "aava-max3107", | 317 | .name = "aava-max3107", |
318 | .bus = &spi_bus_type, | ||
319 | .owner = THIS_MODULE, | 318 | .owner = THIS_MODULE, |
320 | }, | 319 | }, |
321 | .probe = max3107_probe_aava, | 320 | .probe = max3107_probe_aava, |
diff --git a/drivers/tty/serial/max3107.c b/drivers/tty/serial/max3107.c index 7827000db4f5..17c7ba805d98 100644 --- a/drivers/tty/serial/max3107.c +++ b/drivers/tty/serial/max3107.c | |||
@@ -1181,7 +1181,6 @@ static int max3107_probe_generic(struct spi_device *spi) | |||
1181 | static struct spi_driver max3107_driver = { | 1181 | static struct spi_driver max3107_driver = { |
1182 | .driver = { | 1182 | .driver = { |
1183 | .name = "max3107", | 1183 | .name = "max3107", |
1184 | .bus = &spi_bus_type, | ||
1185 | .owner = THIS_MODULE, | 1184 | .owner = THIS_MODULE, |
1186 | }, | 1185 | }, |
1187 | .probe = max3107_probe_generic, | 1186 | .probe = max3107_probe_generic, |
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index e272d3919c67..a9234ba8f8d5 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c | |||
@@ -1154,7 +1154,6 @@ serial_hsu_console_setup(struct console *co, char *options) | |||
1154 | int bits = 8; | 1154 | int bits = 8; |
1155 | int parity = 'n'; | 1155 | int parity = 'n'; |
1156 | int flow = 'n'; | 1156 | int flow = 'n'; |
1157 | int ret; | ||
1158 | 1157 | ||
1159 | if (co->index == -1 || co->index >= serial_hsu_reg.nr) | 1158 | if (co->index == -1 || co->index >= serial_hsu_reg.nr) |
1160 | co->index = 0; | 1159 | co->index = 0; |
@@ -1165,9 +1164,7 @@ serial_hsu_console_setup(struct console *co, char *options) | |||
1165 | if (options) | 1164 | if (options) |
1166 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1165 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
1167 | 1166 | ||
1168 | ret = uart_set_options(&up->port, co, baud, parity, bits, flow); | 1167 | return uart_set_options(&up->port, co, baud, parity, bits, flow); |
1169 | |||
1170 | return ret; | ||
1171 | } | 1168 | } |
1172 | 1169 | ||
1173 | static struct console serial_hsu_console = { | 1170 | static struct console serial_hsu_console = { |
@@ -1176,9 +1173,13 @@ static struct console serial_hsu_console = { | |||
1176 | .device = uart_console_device, | 1173 | .device = uart_console_device, |
1177 | .setup = serial_hsu_console_setup, | 1174 | .setup = serial_hsu_console_setup, |
1178 | .flags = CON_PRINTBUFFER, | 1175 | .flags = CON_PRINTBUFFER, |
1179 | .index = 2, | 1176 | .index = -1, |
1180 | .data = &serial_hsu_reg, | 1177 | .data = &serial_hsu_reg, |
1181 | }; | 1178 | }; |
1179 | |||
1180 | #define SERIAL_HSU_CONSOLE (&serial_hsu_console) | ||
1181 | #else | ||
1182 | #define SERIAL_HSU_CONSOLE NULL | ||
1182 | #endif | 1183 | #endif |
1183 | 1184 | ||
1184 | struct uart_ops serial_hsu_pops = { | 1185 | struct uart_ops serial_hsu_pops = { |
@@ -1208,6 +1209,7 @@ static struct uart_driver serial_hsu_reg = { | |||
1208 | .major = TTY_MAJOR, | 1209 | .major = TTY_MAJOR, |
1209 | .minor = 128, | 1210 | .minor = 128, |
1210 | .nr = 3, | 1211 | .nr = 3, |
1212 | .cons = SERIAL_HSU_CONSOLE, | ||
1211 | }; | 1213 | }; |
1212 | 1214 | ||
1213 | #ifdef CONFIG_PM | 1215 | #ifdef CONFIG_PM |
@@ -1342,12 +1344,6 @@ static int serial_hsu_probe(struct pci_dev *pdev, | |||
1342 | } | 1344 | } |
1343 | uart_add_one_port(&serial_hsu_reg, &uport->port); | 1345 | uart_add_one_port(&serial_hsu_reg, &uport->port); |
1344 | 1346 | ||
1345 | #ifdef CONFIG_SERIAL_MFD_HSU_CONSOLE | ||
1346 | if (index == 2) { | ||
1347 | register_console(&serial_hsu_console); | ||
1348 | uport->port.cons = &serial_hsu_console; | ||
1349 | } | ||
1350 | #endif | ||
1351 | pci_set_drvdata(pdev, uport); | 1347 | pci_set_drvdata(pdev, uport); |
1352 | } | 1348 | } |
1353 | 1349 | ||
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 4c309e869903..df2a2240a3ae 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c | |||
@@ -876,7 +876,6 @@ static int __devexit serial_m3110_remove(struct spi_device *dev) | |||
876 | static struct spi_driver uart_max3110_driver = { | 876 | static struct spi_driver uart_max3110_driver = { |
877 | .driver = { | 877 | .driver = { |
878 | .name = "spi_max3111", | 878 | .name = "spi_max3111", |
879 | .bus = &spi_bus_type, | ||
880 | .owner = THIS_MODULE, | 879 | .owner = THIS_MODULE, |
881 | }, | 880 | }, |
882 | .probe = serial_m3110_probe, | 881 | .probe = serial_m3110_probe, |
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 60c6eb850265..5e85e1e14c44 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c | |||
@@ -422,9 +422,9 @@ static int __devexit msm_hs_remove(struct platform_device *pdev) | |||
422 | msm_uport->rx.rbuffer); | 422 | msm_uport->rx.rbuffer); |
423 | dma_pool_destroy(msm_uport->rx.pool); | 423 | dma_pool_destroy(msm_uport->rx.pool); |
424 | 424 | ||
425 | dma_unmap_single(dev, msm_uport->rx.cmdptr_dmaaddr, sizeof(u32 *), | 425 | dma_unmap_single(dev, msm_uport->rx.cmdptr_dmaaddr, sizeof(u32), |
426 | DMA_TO_DEVICE); | 426 | DMA_TO_DEVICE); |
427 | dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr_ptr, sizeof(u32 *), | 427 | dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr_ptr, sizeof(u32), |
428 | DMA_TO_DEVICE); | 428 | DMA_TO_DEVICE); |
429 | dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr, sizeof(dmov_box), | 429 | dma_unmap_single(dev, msm_uport->tx.mapped_cmd_ptr, sizeof(dmov_box), |
430 | DMA_TO_DEVICE); | 430 | DMA_TO_DEVICE); |
@@ -812,7 +812,7 @@ static void msm_hs_submit_tx_locked(struct uart_port *uport) | |||
812 | *tx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(tx->mapped_cmd_ptr); | 812 | *tx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(tx->mapped_cmd_ptr); |
813 | 813 | ||
814 | dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr_ptr, | 814 | dma_sync_single_for_device(uport->dev, tx->mapped_cmd_ptr_ptr, |
815 | sizeof(u32 *), DMA_TO_DEVICE); | 815 | sizeof(u32), DMA_TO_DEVICE); |
816 | 816 | ||
817 | /* Save tx_count to use in Callback */ | 817 | /* Save tx_count to use in Callback */ |
818 | tx->tx_count = tx_count; | 818 | tx->tx_count = tx_count; |
@@ -1087,12 +1087,10 @@ static void msm_hs_config_port(struct uart_port *uport, int cfg_flags) | |||
1087 | } | 1087 | } |
1088 | 1088 | ||
1089 | /* Handle CTS changes (Called from interrupt handler) */ | 1089 | /* Handle CTS changes (Called from interrupt handler) */ |
1090 | static void msm_hs_handle_delta_cts(struct uart_port *uport) | 1090 | static void msm_hs_handle_delta_cts_locked(struct uart_port *uport) |
1091 | { | 1091 | { |
1092 | unsigned long flags; | ||
1093 | struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); | 1092 | struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); |
1094 | 1093 | ||
1095 | spin_lock_irqsave(&uport->lock, flags); | ||
1096 | clk_enable(msm_uport->clk); | 1094 | clk_enable(msm_uport->clk); |
1097 | 1095 | ||
1098 | /* clear interrupt */ | 1096 | /* clear interrupt */ |
@@ -1100,7 +1098,6 @@ static void msm_hs_handle_delta_cts(struct uart_port *uport) | |||
1100 | uport->icount.cts++; | 1098 | uport->icount.cts++; |
1101 | 1099 | ||
1102 | clk_disable(msm_uport->clk); | 1100 | clk_disable(msm_uport->clk); |
1103 | spin_unlock_irqrestore(&uport->lock, flags); | ||
1104 | 1101 | ||
1105 | /* clear the IOCTL TIOCMIWAIT if called */ | 1102 | /* clear the IOCTL TIOCMIWAIT if called */ |
1106 | wake_up_interruptible(&uport->state->port.delta_msr_wait); | 1103 | wake_up_interruptible(&uport->state->port.delta_msr_wait); |
@@ -1248,7 +1245,7 @@ static irqreturn_t msm_hs_isr(int irq, void *dev) | |||
1248 | 1245 | ||
1249 | /* Change in CTS interrupt */ | 1246 | /* Change in CTS interrupt */ |
1250 | if (isr_status & UARTDM_ISR_DELTA_CTS_BMSK) | 1247 | if (isr_status & UARTDM_ISR_DELTA_CTS_BMSK) |
1251 | msm_hs_handle_delta_cts(uport); | 1248 | msm_hs_handle_delta_cts_locked(uport); |
1252 | 1249 | ||
1253 | spin_unlock_irqrestore(&uport->lock, flags); | 1250 | spin_unlock_irqrestore(&uport->lock, flags); |
1254 | 1251 | ||
@@ -1537,7 +1534,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) | |||
1537 | if (!tx->command_ptr) | 1534 | if (!tx->command_ptr) |
1538 | return -ENOMEM; | 1535 | return -ENOMEM; |
1539 | 1536 | ||
1540 | tx->command_ptr_ptr = kmalloc(sizeof(u32 *), GFP_KERNEL | __GFP_DMA); | 1537 | tx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA); |
1541 | if (!tx->command_ptr_ptr) { | 1538 | if (!tx->command_ptr_ptr) { |
1542 | ret = -ENOMEM; | 1539 | ret = -ENOMEM; |
1543 | goto err_tx_command_ptr_ptr; | 1540 | goto err_tx_command_ptr_ptr; |
@@ -1547,7 +1544,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) | |||
1547 | sizeof(dmov_box), DMA_TO_DEVICE); | 1544 | sizeof(dmov_box), DMA_TO_DEVICE); |
1548 | tx->mapped_cmd_ptr_ptr = dma_map_single(uport->dev, | 1545 | tx->mapped_cmd_ptr_ptr = dma_map_single(uport->dev, |
1549 | tx->command_ptr_ptr, | 1546 | tx->command_ptr_ptr, |
1550 | sizeof(u32 *), DMA_TO_DEVICE); | 1547 | sizeof(u32), DMA_TO_DEVICE); |
1551 | tx->xfer.cmdptr = DMOV_CMD_ADDR(tx->mapped_cmd_ptr_ptr); | 1548 | tx->xfer.cmdptr = DMOV_CMD_ADDR(tx->mapped_cmd_ptr_ptr); |
1552 | 1549 | ||
1553 | init_waitqueue_head(&rx->wait); | 1550 | init_waitqueue_head(&rx->wait); |
@@ -1575,7 +1572,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) | |||
1575 | goto err_rx_command_ptr; | 1572 | goto err_rx_command_ptr; |
1576 | } | 1573 | } |
1577 | 1574 | ||
1578 | rx->command_ptr_ptr = kmalloc(sizeof(u32 *), GFP_KERNEL | __GFP_DMA); | 1575 | rx->command_ptr_ptr = kmalloc(sizeof(u32), GFP_KERNEL | __GFP_DMA); |
1579 | if (!rx->command_ptr_ptr) { | 1576 | if (!rx->command_ptr_ptr) { |
1580 | pr_err("%s(): cannot allocate rx->command_ptr_ptr", __func__); | 1577 | pr_err("%s(): cannot allocate rx->command_ptr_ptr", __func__); |
1581 | ret = -ENOMEM; | 1578 | ret = -ENOMEM; |
@@ -1593,7 +1590,7 @@ static int __devinit uartdm_init_port(struct uart_port *uport) | |||
1593 | *rx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(rx->mapped_cmd_ptr); | 1590 | *rx->command_ptr_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(rx->mapped_cmd_ptr); |
1594 | 1591 | ||
1595 | rx->cmdptr_dmaaddr = dma_map_single(uport->dev, rx->command_ptr_ptr, | 1592 | rx->cmdptr_dmaaddr = dma_map_single(uport->dev, rx->command_ptr_ptr, |
1596 | sizeof(u32 *), DMA_TO_DEVICE); | 1593 | sizeof(u32), DMA_TO_DEVICE); |
1597 | rx->xfer.cmdptr = DMOV_CMD_ADDR(rx->cmdptr_dmaaddr); | 1594 | rx->xfer.cmdptr = DMOV_CMD_ADDR(rx->cmdptr_dmaaddr); |
1598 | 1595 | ||
1599 | INIT_WORK(&rx->tty_work, msm_hs_tty_flip_buffer_work); | 1596 | INIT_WORK(&rx->tty_work, msm_hs_tty_flip_buffer_work); |
@@ -1609,7 +1606,7 @@ err_dma_pool_alloc: | |||
1609 | dma_pool_destroy(msm_uport->rx.pool); | 1606 | dma_pool_destroy(msm_uport->rx.pool); |
1610 | err_dma_pool_create: | 1607 | err_dma_pool_create: |
1611 | dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr_ptr, | 1608 | dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr_ptr, |
1612 | sizeof(u32 *), DMA_TO_DEVICE); | 1609 | sizeof(u32), DMA_TO_DEVICE); |
1613 | dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr, | 1610 | dma_unmap_single(uport->dev, msm_uport->tx.mapped_cmd_ptr, |
1614 | sizeof(dmov_box), DMA_TO_DEVICE); | 1611 | sizeof(dmov_box), DMA_TO_DEVICE); |
1615 | kfree(msm_uport->tx.command_ptr_ptr); | 1612 | kfree(msm_uport->tx.command_ptr_ptr); |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 7e02c9c344fe..076169f50b01 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -145,11 +145,12 @@ static inline void mxs_auart_tx_chars(struct mxs_auart_port *s) | |||
145 | writel(xmit->buf[xmit->tail], | 145 | writel(xmit->buf[xmit->tail], |
146 | s->port.membase + AUART_DATA); | 146 | s->port.membase + AUART_DATA); |
147 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 147 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
148 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
149 | uart_write_wakeup(&s->port); | ||
150 | } else | 148 | } else |
151 | break; | 149 | break; |
152 | } | 150 | } |
151 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
152 | uart_write_wakeup(&s->port); | ||
153 | |||
153 | if (uart_circ_empty(&(s->port.state->xmit))) | 154 | if (uart_circ_empty(&(s->port.state->xmit))) |
154 | writel(AUART_INTR_TXIEN, | 155 | writel(AUART_INTR_TXIEN, |
155 | s->port.membase + AUART_INTR_CLR); | 156 | s->port.membase + AUART_INTR_CLR); |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 5e713d3ef1f4..f2a1380ed678 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -399,7 +399,7 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port) | |||
399 | static unsigned int serial_omap_get_mctrl(struct uart_port *port) | 399 | static unsigned int serial_omap_get_mctrl(struct uart_port *port) |
400 | { | 400 | { |
401 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 401 | struct uart_omap_port *up = (struct uart_omap_port *)port; |
402 | unsigned char status; | 402 | unsigned int status; |
403 | unsigned int ret = 0; | 403 | unsigned int ret = 0; |
404 | 404 | ||
405 | status = check_modem_status(up); | 405 | status = check_modem_status(up); |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index d6aba8c087e4..de0f613ed6f5 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -25,6 +25,9 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/dmi.h> | 27 | #include <linux/dmi.h> |
28 | #include <linux/console.h> | ||
29 | #include <linux/nmi.h> | ||
30 | #include <linux/delay.h> | ||
28 | 31 | ||
29 | #include <linux/dmaengine.h> | 32 | #include <linux/dmaengine.h> |
30 | #include <linux/pch_dma.h> | 33 | #include <linux/pch_dma.h> |
@@ -198,6 +201,10 @@ enum { | |||
198 | 201 | ||
199 | #define PCI_VENDOR_ID_ROHM 0x10DB | 202 | #define PCI_VENDOR_ID_ROHM 0x10DB |
200 | 203 | ||
204 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
205 | |||
206 | #define DEFAULT_BAUD_RATE 1843200 /* 1.8432MHz */ | ||
207 | |||
201 | struct pch_uart_buffer { | 208 | struct pch_uart_buffer { |
202 | unsigned char *buf; | 209 | unsigned char *buf; |
203 | int size; | 210 | int size; |
@@ -276,6 +283,9 @@ static struct pch_uart_driver_data drv_dat[] = { | |||
276 | [pch_ml7831_uart1] = {PCH_UART_2LINE, 1}, | 283 | [pch_ml7831_uart1] = {PCH_UART_2LINE, 1}, |
277 | }; | 284 | }; |
278 | 285 | ||
286 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE | ||
287 | static struct eg20t_port *pch_uart_ports[PCH_UART_NR]; | ||
288 | #endif | ||
279 | static unsigned int default_baud = 9600; | 289 | static unsigned int default_baud = 9600; |
280 | static const int trigger_level_256[4] = { 1, 64, 128, 224 }; | 290 | static const int trigger_level_256[4] = { 1, 64, 128, 224 }; |
281 | static const int trigger_level_64[4] = { 1, 16, 32, 56 }; | 291 | static const int trigger_level_64[4] = { 1, 16, 32, 56 }; |
@@ -1385,6 +1395,143 @@ static struct uart_ops pch_uart_ops = { | |||
1385 | .verify_port = pch_uart_verify_port | 1395 | .verify_port = pch_uart_verify_port |
1386 | }; | 1396 | }; |
1387 | 1397 | ||
1398 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE | ||
1399 | |||
1400 | /* | ||
1401 | * Wait for transmitter & holding register to empty | ||
1402 | */ | ||
1403 | static void wait_for_xmitr(struct eg20t_port *up, int bits) | ||
1404 | { | ||
1405 | unsigned int status, tmout = 10000; | ||
1406 | |||
1407 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
1408 | for (;;) { | ||
1409 | status = ioread8(up->membase + UART_LSR); | ||
1410 | |||
1411 | if ((status & bits) == bits) | ||
1412 | break; | ||
1413 | if (--tmout == 0) | ||
1414 | break; | ||
1415 | udelay(1); | ||
1416 | } | ||
1417 | |||
1418 | /* Wait up to 1s for flow control if necessary */ | ||
1419 | if (up->port.flags & UPF_CONS_FLOW) { | ||
1420 | unsigned int tmout; | ||
1421 | for (tmout = 1000000; tmout; tmout--) { | ||
1422 | unsigned int msr = ioread8(up->membase + UART_MSR); | ||
1423 | if (msr & UART_MSR_CTS) | ||
1424 | break; | ||
1425 | udelay(1); | ||
1426 | touch_nmi_watchdog(); | ||
1427 | } | ||
1428 | } | ||
1429 | } | ||
1430 | |||
1431 | static void pch_console_putchar(struct uart_port *port, int ch) | ||
1432 | { | ||
1433 | struct eg20t_port *priv = | ||
1434 | container_of(port, struct eg20t_port, port); | ||
1435 | |||
1436 | wait_for_xmitr(priv, UART_LSR_THRE); | ||
1437 | iowrite8(ch, priv->membase + PCH_UART_THR); | ||
1438 | } | ||
1439 | |||
1440 | /* | ||
1441 | * Print a string to the serial port trying not to disturb | ||
1442 | * any possible real use of the port... | ||
1443 | * | ||
1444 | * The console_lock must be held when we get here. | ||
1445 | */ | ||
1446 | static void | ||
1447 | pch_console_write(struct console *co, const char *s, unsigned int count) | ||
1448 | { | ||
1449 | struct eg20t_port *priv; | ||
1450 | |||
1451 | unsigned long flags; | ||
1452 | u8 ier; | ||
1453 | int locked = 1; | ||
1454 | |||
1455 | priv = pch_uart_ports[co->index]; | ||
1456 | |||
1457 | touch_nmi_watchdog(); | ||
1458 | |||
1459 | local_irq_save(flags); | ||
1460 | if (priv->port.sysrq) { | ||
1461 | /* serial8250_handle_port() already took the lock */ | ||
1462 | locked = 0; | ||
1463 | } else if (oops_in_progress) { | ||
1464 | locked = spin_trylock(&priv->port.lock); | ||
1465 | } else | ||
1466 | spin_lock(&priv->port.lock); | ||
1467 | |||
1468 | /* | ||
1469 | * First save the IER then disable the interrupts | ||
1470 | */ | ||
1471 | ier = ioread8(priv->membase + UART_IER); | ||
1472 | |||
1473 | pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_ALL_INT); | ||
1474 | |||
1475 | uart_console_write(&priv->port, s, count, pch_console_putchar); | ||
1476 | |||
1477 | /* | ||
1478 | * Finally, wait for transmitter to become empty | ||
1479 | * and restore the IER | ||
1480 | */ | ||
1481 | wait_for_xmitr(priv, BOTH_EMPTY); | ||
1482 | iowrite8(ier, priv->membase + UART_IER); | ||
1483 | |||
1484 | if (locked) | ||
1485 | spin_unlock(&priv->port.lock); | ||
1486 | local_irq_restore(flags); | ||
1487 | } | ||
1488 | |||
1489 | static int __init pch_console_setup(struct console *co, char *options) | ||
1490 | { | ||
1491 | struct uart_port *port; | ||
1492 | int baud = 9600; | ||
1493 | int bits = 8; | ||
1494 | int parity = 'n'; | ||
1495 | int flow = 'n'; | ||
1496 | |||
1497 | /* | ||
1498 | * Check whether an invalid uart number has been specified, and | ||
1499 | * if so, search for the first available port that does have | ||
1500 | * console support. | ||
1501 | */ | ||
1502 | if (co->index >= PCH_UART_NR) | ||
1503 | co->index = 0; | ||
1504 | port = &pch_uart_ports[co->index]->port; | ||
1505 | |||
1506 | if (!port || (!port->iobase && !port->membase)) | ||
1507 | return -ENODEV; | ||
1508 | |||
1509 | /* setup uartclock */ | ||
1510 | port->uartclk = DEFAULT_BAUD_RATE; | ||
1511 | |||
1512 | if (options) | ||
1513 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
1514 | |||
1515 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
1516 | } | ||
1517 | |||
1518 | static struct uart_driver pch_uart_driver; | ||
1519 | |||
1520 | static struct console pch_console = { | ||
1521 | .name = PCH_UART_DRIVER_DEVICE, | ||
1522 | .write = pch_console_write, | ||
1523 | .device = uart_console_device, | ||
1524 | .setup = pch_console_setup, | ||
1525 | .flags = CON_PRINTBUFFER | CON_ANYTIME, | ||
1526 | .index = -1, | ||
1527 | .data = &pch_uart_driver, | ||
1528 | }; | ||
1529 | |||
1530 | #define PCH_CONSOLE (&pch_console) | ||
1531 | #else | ||
1532 | #define PCH_CONSOLE NULL | ||
1533 | #endif | ||
1534 | |||
1388 | static struct uart_driver pch_uart_driver = { | 1535 | static struct uart_driver pch_uart_driver = { |
1389 | .owner = THIS_MODULE, | 1536 | .owner = THIS_MODULE, |
1390 | .driver_name = KBUILD_MODNAME, | 1537 | .driver_name = KBUILD_MODNAME, |
@@ -1392,6 +1539,7 @@ static struct uart_driver pch_uart_driver = { | |||
1392 | .major = 0, | 1539 | .major = 0, |
1393 | .minor = 0, | 1540 | .minor = 0, |
1394 | .nr = PCH_UART_NR, | 1541 | .nr = PCH_UART_NR, |
1542 | .cons = PCH_CONSOLE, | ||
1395 | }; | 1543 | }; |
1396 | 1544 | ||
1397 | static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | 1545 | static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, |
@@ -1418,7 +1566,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
1418 | if (!rxbuf) | 1566 | if (!rxbuf) |
1419 | goto init_port_free_txbuf; | 1567 | goto init_port_free_txbuf; |
1420 | 1568 | ||
1421 | base_baud = 1843200; /* 1.8432MHz */ | 1569 | base_baud = DEFAULT_BAUD_RATE; |
1422 | 1570 | ||
1423 | /* quirk for CM-iTC board */ | 1571 | /* quirk for CM-iTC board */ |
1424 | board_name = dmi_get_system_info(DMI_BOARD_NAME); | 1572 | board_name = dmi_get_system_info(DMI_BOARD_NAME); |
@@ -1468,6 +1616,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
1468 | pci_set_drvdata(pdev, priv); | 1616 | pci_set_drvdata(pdev, priv); |
1469 | pch_uart_hal_request(pdev, fifosize, base_baud); | 1617 | pch_uart_hal_request(pdev, fifosize, base_baud); |
1470 | 1618 | ||
1619 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE | ||
1620 | pch_uart_ports[board->line_no] = priv; | ||
1621 | #endif | ||
1471 | ret = uart_add_one_port(&pch_uart_driver, &priv->port); | 1622 | ret = uart_add_one_port(&pch_uart_driver, &priv->port); |
1472 | if (ret < 0) | 1623 | if (ret < 0) |
1473 | goto init_port_hal_free; | 1624 | goto init_port_hal_free; |
@@ -1475,6 +1626,9 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, | |||
1475 | return priv; | 1626 | return priv; |
1476 | 1627 | ||
1477 | init_port_hal_free: | 1628 | init_port_hal_free: |
1629 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE | ||
1630 | pch_uart_ports[board->line_no] = NULL; | ||
1631 | #endif | ||
1478 | free_page((unsigned long)rxbuf); | 1632 | free_page((unsigned long)rxbuf); |
1479 | init_port_free_txbuf: | 1633 | init_port_free_txbuf: |
1480 | kfree(priv); | 1634 | kfree(priv); |
@@ -1497,6 +1651,10 @@ static void pch_uart_pci_remove(struct pci_dev *pdev) | |||
1497 | priv = (struct eg20t_port *)pci_get_drvdata(pdev); | 1651 | priv = (struct eg20t_port *)pci_get_drvdata(pdev); |
1498 | 1652 | ||
1499 | pci_disable_msi(pdev); | 1653 | pci_disable_msi(pdev); |
1654 | |||
1655 | #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE | ||
1656 | pch_uart_ports[priv->port.line] = NULL; | ||
1657 | #endif | ||
1500 | pch_uart_exit_port(priv); | 1658 | pch_uart_exit_port(priv); |
1501 | pci_disable_device(pdev); | 1659 | pci_disable_device(pdev); |
1502 | kfree(priv); | 1660 | kfree(priv); |
diff --git a/drivers/tty/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c index 75038ad2b242..e0b4b0a30a5a 100644 --- a/drivers/tty/serial/sc26xx.c +++ b/drivers/tty/serial/sc26xx.c | |||
@@ -736,19 +736,7 @@ static struct platform_driver sc26xx_driver = { | |||
736 | }, | 736 | }, |
737 | }; | 737 | }; |
738 | 738 | ||
739 | static int __init sc26xx_init(void) | 739 | module_platform_driver(sc26xx_driver); |
740 | { | ||
741 | return platform_driver_register(&sc26xx_driver); | ||
742 | } | ||
743 | |||
744 | static void __exit sc26xx_exit(void) | ||
745 | { | ||
746 | platform_driver_unregister(&sc26xx_driver); | ||
747 | } | ||
748 | |||
749 | module_init(sc26xx_init); | ||
750 | module_exit(sc26xx_exit); | ||
751 | |||
752 | 740 | ||
753 | MODULE_AUTHOR("Thomas Bogendörfer"); | 741 | MODULE_AUTHOR("Thomas Bogendörfer"); |
754 | MODULE_DESCRIPTION("SC681/SC2692 serial driver"); | 742 | MODULE_DESCRIPTION("SC681/SC2692 serial driver"); |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0406d7ff505e..c7bf31a6a7e7 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -22,6 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/tty.h> | 24 | #include <linux/tty.h> |
25 | #include <linux/tty_flip.h> | ||
25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
26 | #include <linux/init.h> | 27 | #include <linux/init.h> |
27 | #include <linux/console.h> | 28 | #include <linux/console.h> |
@@ -60,6 +61,8 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | |||
60 | 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); |
61 | static void uart_change_pm(struct uart_state *state, int pm_state); | 62 | static void uart_change_pm(struct uart_state *state, int pm_state); |
62 | 63 | ||
64 | static void uart_port_shutdown(struct tty_port *port); | ||
65 | |||
63 | /* | 66 | /* |
64 | * This routine is used by the interrupt handler to schedule processing in | 67 | * This routine is used by the interrupt handler to schedule processing in |
65 | * the software interrupt portion of the driver. | 68 | * the software interrupt portion of the driver. |
@@ -128,25 +131,16 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) | |||
128 | * Startup the port. This will be called once per open. All calls | 131 | * Startup the port. This will be called once per open. All calls |
129 | * will be serialised by the per-port mutex. | 132 | * will be serialised by the per-port mutex. |
130 | */ | 133 | */ |
131 | static int uart_startup(struct tty_struct *tty, struct uart_state *state, int init_hw) | 134 | static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, |
135 | int init_hw) | ||
132 | { | 136 | { |
133 | struct uart_port *uport = state->uart_port; | 137 | struct uart_port *uport = state->uart_port; |
134 | struct tty_port *port = &state->port; | 138 | struct tty_port *port = &state->port; |
135 | unsigned long page; | 139 | unsigned long page; |
136 | int retval = 0; | 140 | int retval = 0; |
137 | 141 | ||
138 | if (port->flags & ASYNC_INITIALIZED) | ||
139 | return 0; | ||
140 | |||
141 | /* | ||
142 | * Set the TTY IO error marker - we will only clear this | ||
143 | * once we have successfully opened the port. Also set | ||
144 | * up the tty->alt_speed kludge | ||
145 | */ | ||
146 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
147 | |||
148 | if (uport->type == PORT_UNKNOWN) | 142 | if (uport->type == PORT_UNKNOWN) |
149 | return 0; | 143 | return 1; |
150 | 144 | ||
151 | /* | 145 | /* |
152 | * Initialise and allocate the transmit and temporary | 146 | * Initialise and allocate the transmit and temporary |
@@ -188,10 +182,6 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in | |||
188 | tty->hw_stopped = 1; | 182 | tty->hw_stopped = 1; |
189 | spin_unlock_irq(&uport->lock); | 183 | spin_unlock_irq(&uport->lock); |
190 | } | 184 | } |
191 | |||
192 | set_bit(ASYNCB_INITIALIZED, &port->flags); | ||
193 | |||
194 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
195 | } | 185 | } |
196 | 186 | ||
197 | /* | 187 | /* |
@@ -200,6 +190,31 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in | |||
200 | * now. | 190 | * now. |
201 | */ | 191 | */ |
202 | if (retval && capable(CAP_SYS_ADMIN)) | 192 | if (retval && capable(CAP_SYS_ADMIN)) |
193 | return 1; | ||
194 | |||
195 | return retval; | ||
196 | } | ||
197 | |||
198 | static int uart_startup(struct tty_struct *tty, struct uart_state *state, | ||
199 | int init_hw) | ||
200 | { | ||
201 | struct tty_port *port = &state->port; | ||
202 | int retval; | ||
203 | |||
204 | if (port->flags & ASYNC_INITIALIZED) | ||
205 | return 0; | ||
206 | |||
207 | /* | ||
208 | * Set the TTY IO error marker - we will only clear this | ||
209 | * once we have successfully opened the port. | ||
210 | */ | ||
211 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
212 | |||
213 | retval = uart_port_startup(tty, state, init_hw); | ||
214 | if (!retval) { | ||
215 | set_bit(ASYNCB_INITIALIZED, &port->flags); | ||
216 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
217 | } else if (retval > 0) | ||
203 | retval = 0; | 218 | retval = 0; |
204 | 219 | ||
205 | return retval; | 220 | return retval; |
@@ -228,24 +243,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) | |||
228 | if (!tty || (tty->termios->c_cflag & HUPCL)) | 243 | if (!tty || (tty->termios->c_cflag & HUPCL)) |
229 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 244 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
230 | 245 | ||
231 | /* | 246 | uart_port_shutdown(port); |
232 | * clear delta_msr_wait queue to avoid mem leaks: we may free | ||
233 | * the irq here so the queue might never be woken up. Note | ||
234 | * that we won't end up waiting on delta_msr_wait again since | ||
235 | * any outstanding file descriptors should be pointing at | ||
236 | * hung_up_tty_fops now. | ||
237 | */ | ||
238 | wake_up_interruptible(&port->delta_msr_wait); | ||
239 | |||
240 | /* | ||
241 | * Free the IRQ and disable the port. | ||
242 | */ | ||
243 | uport->ops->shutdown(uport); | ||
244 | |||
245 | /* | ||
246 | * Ensure that the IRQ handler isn't running on another CPU. | ||
247 | */ | ||
248 | synchronize_irq(uport->irq); | ||
249 | } | 247 | } |
250 | 248 | ||
251 | /* | 249 | /* |
@@ -423,7 +421,7 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) | |||
423 | if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) | 421 | if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) |
424 | quot = port->custom_divisor; | 422 | quot = port->custom_divisor; |
425 | else | 423 | else |
426 | quot = (port->uartclk + (8 * baud)) / (16 * baud); | 424 | quot = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud); |
427 | 425 | ||
428 | return quot; | 426 | return quot; |
429 | } | 427 | } |
@@ -658,10 +656,10 @@ static int uart_get_info(struct uart_state *state, | |||
658 | tmp.flags = uport->flags; | 656 | tmp.flags = uport->flags; |
659 | tmp.xmit_fifo_size = uport->fifosize; | 657 | tmp.xmit_fifo_size = uport->fifosize; |
660 | tmp.baud_base = uport->uartclk / 16; | 658 | tmp.baud_base = uport->uartclk / 16; |
661 | tmp.close_delay = port->close_delay / 10; | 659 | tmp.close_delay = jiffies_to_msecs(port->close_delay) / 10; |
662 | tmp.closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 660 | tmp.closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
663 | ASYNC_CLOSING_WAIT_NONE : | 661 | ASYNC_CLOSING_WAIT_NONE : |
664 | port->closing_wait / 10; | 662 | jiffies_to_msecs(port->closing_wait) / 10; |
665 | tmp.custom_divisor = uport->custom_divisor; | 663 | tmp.custom_divisor = uport->custom_divisor; |
666 | tmp.hub6 = uport->hub6; | 664 | tmp.hub6 = uport->hub6; |
667 | tmp.io_type = uport->iotype; | 665 | tmp.io_type = uport->iotype; |
@@ -695,9 +693,10 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
695 | new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; | 693 | new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; |
696 | 694 | ||
697 | new_serial.irq = irq_canonicalize(new_serial.irq); | 695 | new_serial.irq = irq_canonicalize(new_serial.irq); |
698 | close_delay = new_serial.close_delay * 10; | 696 | close_delay = msecs_to_jiffies(new_serial.close_delay * 10); |
699 | closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 697 | closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
700 | ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; | 698 | ASYNC_CLOSING_WAIT_NONE : |
699 | msecs_to_jiffies(new_serial.closing_wait * 10); | ||
701 | 700 | ||
702 | /* | 701 | /* |
703 | * This semaphore protects port->count. It is also | 702 | * This semaphore protects port->count. It is also |
@@ -1265,47 +1264,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1265 | 1264 | ||
1266 | pr_debug("uart_close(%d) called\n", uport->line); | 1265 | pr_debug("uart_close(%d) called\n", uport->line); |
1267 | 1266 | ||
1268 | spin_lock_irqsave(&port->lock, flags); | 1267 | if (tty_port_close_start(port, tty, filp) == 0) |
1269 | |||
1270 | if (tty_hung_up_p(filp)) { | ||
1271 | spin_unlock_irqrestore(&port->lock, flags); | ||
1272 | return; | 1268 | return; |
1273 | } | ||
1274 | |||
1275 | if ((tty->count == 1) && (port->count != 1)) { | ||
1276 | /* | ||
1277 | * Uh, oh. tty->count is 1, which means that the tty | ||
1278 | * structure will be freed. port->count should always | ||
1279 | * be one in these conditions. If it's greater than | ||
1280 | * one, we've got real problems, since it means the | ||
1281 | * serial port won't be shutdown. | ||
1282 | */ | ||
1283 | printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, " | ||
1284 | "port->count is %d\n", port->count); | ||
1285 | port->count = 1; | ||
1286 | } | ||
1287 | if (--port->count < 0) { | ||
1288 | printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n", | ||
1289 | tty->name, port->count); | ||
1290 | port->count = 0; | ||
1291 | } | ||
1292 | if (port->count) { | ||
1293 | spin_unlock_irqrestore(&port->lock, flags); | ||
1294 | return; | ||
1295 | } | ||
1296 | |||
1297 | /* | ||
1298 | * Now we wait for the transmit buffer to clear; and we notify | ||
1299 | * the line discipline to only process XON/XOFF characters by | ||
1300 | * setting tty->closing. | ||
1301 | */ | ||
1302 | set_bit(ASYNCB_CLOSING, &port->flags); | ||
1303 | tty->closing = 1; | ||
1304 | spin_unlock_irqrestore(&port->lock, flags); | ||
1305 | |||
1306 | if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
1307 | tty_wait_until_sent_from_close(tty, | ||
1308 | msecs_to_jiffies(port->closing_wait)); | ||
1309 | 1269 | ||
1310 | /* | 1270 | /* |
1311 | * At this point, we stop accepting input. To do this, we | 1271 | * At this point, we stop accepting input. To do this, we |
@@ -1337,7 +1297,8 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1337 | if (port->blocked_open) { | 1297 | if (port->blocked_open) { |
1338 | spin_unlock_irqrestore(&port->lock, flags); | 1298 | spin_unlock_irqrestore(&port->lock, flags); |
1339 | if (port->close_delay) | 1299 | if (port->close_delay) |
1340 | msleep_interruptible(port->close_delay); | 1300 | msleep_interruptible( |
1301 | jiffies_to_msecs(port->close_delay)); | ||
1341 | spin_lock_irqsave(&port->lock, flags); | 1302 | spin_lock_irqsave(&port->lock, flags); |
1342 | } else if (!uart_console(uport)) { | 1303 | } else if (!uart_console(uport)) { |
1343 | spin_unlock_irqrestore(&port->lock, flags); | 1304 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -1441,6 +1402,36 @@ static void uart_hangup(struct tty_struct *tty) | |||
1441 | mutex_unlock(&port->mutex); | 1402 | mutex_unlock(&port->mutex); |
1442 | } | 1403 | } |
1443 | 1404 | ||
1405 | static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) | ||
1406 | { | ||
1407 | return 0; | ||
1408 | } | ||
1409 | |||
1410 | static void uart_port_shutdown(struct tty_port *port) | ||
1411 | { | ||
1412 | struct uart_state *state = container_of(port, struct uart_state, port); | ||
1413 | struct uart_port *uport = state->uart_port; | ||
1414 | |||
1415 | /* | ||
1416 | * clear delta_msr_wait queue to avoid mem leaks: we may free | ||
1417 | * the irq here so the queue might never be woken up. Note | ||
1418 | * that we won't end up waiting on delta_msr_wait again since | ||
1419 | * any outstanding file descriptors should be pointing at | ||
1420 | * hung_up_tty_fops now. | ||
1421 | */ | ||
1422 | wake_up_interruptible(&port->delta_msr_wait); | ||
1423 | |||
1424 | /* | ||
1425 | * Free the IRQ and disable the port. | ||
1426 | */ | ||
1427 | uport->ops->shutdown(uport); | ||
1428 | |||
1429 | /* | ||
1430 | * Ensure that the IRQ handler isn't running on another CPU. | ||
1431 | */ | ||
1432 | synchronize_irq(uport->irq); | ||
1433 | } | ||
1434 | |||
1444 | static int uart_carrier_raised(struct tty_port *port) | 1435 | static int uart_carrier_raised(struct tty_port *port) |
1445 | { | 1436 | { |
1446 | struct uart_state *state = container_of(port, struct uart_state, port); | 1437 | struct uart_state *state = container_of(port, struct uart_state, port); |
@@ -1466,33 +1457,6 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) | |||
1466 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 1457 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
1467 | } | 1458 | } |
1468 | 1459 | ||
1469 | static struct uart_state *uart_get(struct uart_driver *drv, int line) | ||
1470 | { | ||
1471 | struct uart_state *state; | ||
1472 | struct tty_port *port; | ||
1473 | int ret = 0; | ||
1474 | |||
1475 | state = drv->state + line; | ||
1476 | port = &state->port; | ||
1477 | if (mutex_lock_interruptible(&port->mutex)) { | ||
1478 | ret = -ERESTARTSYS; | ||
1479 | goto err; | ||
1480 | } | ||
1481 | |||
1482 | port->count++; | ||
1483 | if (!state->uart_port || state->uart_port->flags & UPF_DEAD) { | ||
1484 | ret = -ENXIO; | ||
1485 | goto err_unlock; | ||
1486 | } | ||
1487 | return state; | ||
1488 | |||
1489 | err_unlock: | ||
1490 | port->count--; | ||
1491 | mutex_unlock(&port->mutex); | ||
1492 | err: | ||
1493 | return ERR_PTR(ret); | ||
1494 | } | ||
1495 | |||
1496 | /* | 1460 | /* |
1497 | * calls to uart_open are serialised by the BKL in | 1461 | * calls to uart_open are serialised by the BKL in |
1498 | * fs/char_dev.c:chrdev_open() | 1462 | * fs/char_dev.c:chrdev_open() |
@@ -1506,26 +1470,29 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line) | |||
1506 | static int uart_open(struct tty_struct *tty, struct file *filp) | 1470 | static int uart_open(struct tty_struct *tty, struct file *filp) |
1507 | { | 1471 | { |
1508 | struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; | 1472 | struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; |
1509 | struct uart_state *state; | ||
1510 | struct tty_port *port; | ||
1511 | int retval, line = tty->index; | 1473 | int retval, line = tty->index; |
1474 | struct uart_state *state = drv->state + line; | ||
1475 | struct tty_port *port = &state->port; | ||
1512 | 1476 | ||
1513 | pr_debug("uart_open(%d) called\n", line); | 1477 | pr_debug("uart_open(%d) called\n", line); |
1514 | 1478 | ||
1515 | /* | 1479 | /* |
1516 | * We take the semaphore inside uart_get to guarantee that we won't | 1480 | * We take the semaphore here to guarantee that we won't be re-entered |
1517 | * be re-entered while allocating the state structure, or while we | 1481 | * while allocating the state structure, or while we request any IRQs |
1518 | * request any IRQs that the driver may need. This also has the nice | 1482 | * that the driver may need. This also has the nice side-effect that |
1519 | * side-effect that it delays the action of uart_hangup, so we can | 1483 | * it delays the action of uart_hangup, so we can guarantee that |
1520 | * guarantee that state->port.tty will always contain something | 1484 | * state->port.tty will always contain something reasonable. |
1521 | * reasonable. | ||
1522 | */ | 1485 | */ |
1523 | state = uart_get(drv, line); | 1486 | if (mutex_lock_interruptible(&port->mutex)) { |
1524 | if (IS_ERR(state)) { | 1487 | retval = -ERESTARTSYS; |
1525 | retval = PTR_ERR(state); | 1488 | goto end; |
1526 | goto fail; | 1489 | } |
1490 | |||
1491 | port->count++; | ||
1492 | if (!state->uart_port || state->uart_port->flags & UPF_DEAD) { | ||
1493 | retval = -ENXIO; | ||
1494 | goto err_dec_count; | ||
1527 | } | 1495 | } |
1528 | port = &state->port; | ||
1529 | 1496 | ||
1530 | /* | 1497 | /* |
1531 | * Once we set tty->driver_data here, we are guaranteed that | 1498 | * Once we set tty->driver_data here, we are guaranteed that |
@@ -1535,7 +1502,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1535 | tty->driver_data = state; | 1502 | tty->driver_data = state; |
1536 | state->uart_port->state = state; | 1503 | state->uart_port->state = state; |
1537 | tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; | 1504 | tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; |
1538 | tty->alt_speed = 0; | ||
1539 | tty_port_tty_set(port, tty); | 1505 | tty_port_tty_set(port, tty); |
1540 | 1506 | ||
1541 | /* | 1507 | /* |
@@ -1543,9 +1509,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1543 | */ | 1509 | */ |
1544 | if (tty_hung_up_p(filp)) { | 1510 | if (tty_hung_up_p(filp)) { |
1545 | retval = -EAGAIN; | 1511 | retval = -EAGAIN; |
1546 | port->count--; | 1512 | goto err_dec_count; |
1547 | mutex_unlock(&port->mutex); | ||
1548 | goto fail; | ||
1549 | } | 1513 | } |
1550 | 1514 | ||
1551 | /* | 1515 | /* |
@@ -1566,8 +1530,12 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1566 | if (retval == 0) | 1530 | if (retval == 0) |
1567 | retval = tty_port_block_til_ready(port, tty, filp); | 1531 | retval = tty_port_block_til_ready(port, tty, filp); |
1568 | 1532 | ||
1569 | fail: | 1533 | end: |
1570 | return retval; | 1534 | return retval; |
1535 | err_dec_count: | ||
1536 | port->count--; | ||
1537 | mutex_unlock(&port->mutex); | ||
1538 | goto end; | ||
1571 | } | 1539 | } |
1572 | 1540 | ||
1573 | static const char *uart_type(struct uart_port *port) | 1541 | static const char *uart_type(struct uart_port *port) |
@@ -1858,6 +1826,14 @@ uart_set_options(struct uart_port *port, struct console *co, | |||
1858 | EXPORT_SYMBOL_GPL(uart_set_options); | 1826 | EXPORT_SYMBOL_GPL(uart_set_options); |
1859 | #endif /* CONFIG_SERIAL_CORE_CONSOLE */ | 1827 | #endif /* CONFIG_SERIAL_CORE_CONSOLE */ |
1860 | 1828 | ||
1829 | /** | ||
1830 | * uart_change_pm - set power state of the port | ||
1831 | * | ||
1832 | * @state: port descriptor | ||
1833 | * @pm_state: new state | ||
1834 | * | ||
1835 | * Locking: port->mutex has to be held | ||
1836 | */ | ||
1861 | static void uart_change_pm(struct uart_state *state, int pm_state) | 1837 | static void uart_change_pm(struct uart_state *state, int pm_state) |
1862 | { | 1838 | { |
1863 | struct uart_port *port = state->uart_port; | 1839 | struct uart_port *port = state->uart_port; |
@@ -2214,6 +2190,8 @@ static const struct tty_operations uart_ops = { | |||
2214 | }; | 2190 | }; |
2215 | 2191 | ||
2216 | static const struct tty_port_operations uart_port_ops = { | 2192 | static const struct tty_port_operations uart_port_ops = { |
2193 | .activate = uart_port_activate, | ||
2194 | .shutdown = uart_port_shutdown, | ||
2217 | .carrier_raised = uart_carrier_raised, | 2195 | .carrier_raised = uart_carrier_raised, |
2218 | .dtr_rts = uart_dtr_rts, | 2196 | .dtr_rts = uart_dtr_rts, |
2219 | }; | 2197 | }; |
@@ -2275,8 +2253,8 @@ int uart_register_driver(struct uart_driver *drv) | |||
2275 | 2253 | ||
2276 | tty_port_init(port); | 2254 | tty_port_init(port); |
2277 | port->ops = &uart_port_ops; | 2255 | port->ops = &uart_port_ops; |
2278 | port->close_delay = 500; /* .5 seconds */ | 2256 | port->close_delay = HZ / 2; /* .5 seconds */ |
2279 | port->closing_wait = 30000; /* 30 seconds */ | 2257 | port->closing_wait = 30 * HZ;/* 30 seconds */ |
2280 | } | 2258 | } |
2281 | 2259 | ||
2282 | retval = tty_register_driver(normal); | 2260 | retval = tty_register_driver(normal); |
@@ -2467,6 +2445,99 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) | |||
2467 | } | 2445 | } |
2468 | EXPORT_SYMBOL(uart_match_port); | 2446 | EXPORT_SYMBOL(uart_match_port); |
2469 | 2447 | ||
2448 | /** | ||
2449 | * uart_handle_dcd_change - handle a change of carrier detect state | ||
2450 | * @uport: uart_port structure for the open port | ||
2451 | * @status: new carrier detect status, nonzero if active | ||
2452 | */ | ||
2453 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | ||
2454 | { | ||
2455 | struct uart_state *state = uport->state; | ||
2456 | struct tty_port *port = &state->port; | ||
2457 | struct tty_ldisc *ld = tty_ldisc_ref(port->tty); | ||
2458 | struct pps_event_time ts; | ||
2459 | |||
2460 | if (ld && ld->ops->dcd_change) | ||
2461 | pps_get_ts(&ts); | ||
2462 | |||
2463 | uport->icount.dcd++; | ||
2464 | #ifdef CONFIG_HARD_PPS | ||
2465 | if ((uport->flags & UPF_HARDPPS_CD) && status) | ||
2466 | hardpps(); | ||
2467 | #endif | ||
2468 | |||
2469 | if (port->flags & ASYNC_CHECK_CD) { | ||
2470 | if (status) | ||
2471 | wake_up_interruptible(&port->open_wait); | ||
2472 | else if (port->tty) | ||
2473 | tty_hangup(port->tty); | ||
2474 | } | ||
2475 | |||
2476 | if (ld && ld->ops->dcd_change) | ||
2477 | ld->ops->dcd_change(port->tty, status, &ts); | ||
2478 | if (ld) | ||
2479 | tty_ldisc_deref(ld); | ||
2480 | } | ||
2481 | EXPORT_SYMBOL_GPL(uart_handle_dcd_change); | ||
2482 | |||
2483 | /** | ||
2484 | * uart_handle_cts_change - handle a change of clear-to-send state | ||
2485 | * @uport: uart_port structure for the open port | ||
2486 | * @status: new clear to send status, nonzero if active | ||
2487 | */ | ||
2488 | void uart_handle_cts_change(struct uart_port *uport, unsigned int status) | ||
2489 | { | ||
2490 | struct tty_port *port = &uport->state->port; | ||
2491 | struct tty_struct *tty = port->tty; | ||
2492 | |||
2493 | uport->icount.cts++; | ||
2494 | |||
2495 | if (port->flags & ASYNC_CTS_FLOW) { | ||
2496 | if (tty->hw_stopped) { | ||
2497 | if (status) { | ||
2498 | tty->hw_stopped = 0; | ||
2499 | uport->ops->start_tx(uport); | ||
2500 | uart_write_wakeup(uport); | ||
2501 | } | ||
2502 | } else { | ||
2503 | if (!status) { | ||
2504 | tty->hw_stopped = 1; | ||
2505 | uport->ops->stop_tx(uport); | ||
2506 | } | ||
2507 | } | ||
2508 | } | ||
2509 | } | ||
2510 | EXPORT_SYMBOL_GPL(uart_handle_cts_change); | ||
2511 | |||
2512 | /** | ||
2513 | * uart_insert_char - push a char to the uart layer | ||
2514 | * | ||
2515 | * User is responsible to call tty_flip_buffer_push when they are done with | ||
2516 | * insertion. | ||
2517 | * | ||
2518 | * @port: corresponding port | ||
2519 | * @status: state of the serial port RX buffer (LSR for 8250) | ||
2520 | * @overrun: mask of overrun bits in @status | ||
2521 | * @ch: character to push | ||
2522 | * @flag: flag for the character (see TTY_NORMAL and friends) | ||
2523 | */ | ||
2524 | void uart_insert_char(struct uart_port *port, unsigned int status, | ||
2525 | unsigned int overrun, unsigned int ch, unsigned int flag) | ||
2526 | { | ||
2527 | struct tty_struct *tty = port->state->port.tty; | ||
2528 | |||
2529 | if ((status & port->ignore_status_mask & ~overrun) == 0) | ||
2530 | tty_insert_flip_char(tty, ch, flag); | ||
2531 | |||
2532 | /* | ||
2533 | * Overrun is special. Since it's reported immediately, | ||
2534 | * it doesn't affect the current character. | ||
2535 | */ | ||
2536 | if (status & ~port->ignore_status_mask & overrun) | ||
2537 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
2538 | } | ||
2539 | EXPORT_SYMBOL_GPL(uart_insert_char); | ||
2540 | |||
2470 | EXPORT_SYMBOL(uart_write_wakeup); | 2541 | EXPORT_SYMBOL(uart_write_wakeup); |
2471 | EXPORT_SYMBOL(uart_register_driver); | 2542 | EXPORT_SYMBOL(uart_register_driver); |
2472 | EXPORT_SYMBOL(uart_unregister_driver); | 2543 | EXPORT_SYMBOL(uart_unregister_driver); |
diff --git a/drivers/tty/serial/serial_cs.c b/drivers/tty/serial/serial_cs.c index eef736ff810a..86090605a84e 100644 --- a/drivers/tty/serial/serial_cs.c +++ b/drivers/tty/serial/serial_cs.c | |||
@@ -317,7 +317,7 @@ static int serial_probe(struct pcmcia_device *link) | |||
317 | info->p_dev = link; | 317 | info->p_dev = link; |
318 | link->priv = info; | 318 | link->priv = info; |
319 | 319 | ||
320 | link->config_flags |= CONF_ENABLE_IRQ; | 320 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; |
321 | if (do_sound) | 321 | if (do_sound) |
322 | link->config_flags |= CONF_ENABLE_SPKR; | 322 | link->config_flags |= CONF_ENABLE_SPKR; |
323 | 323 | ||
@@ -445,7 +445,7 @@ static int simple_config(struct pcmcia_device *link) | |||
445 | 445 | ||
446 | /* First pass: look for a config entry that looks normal. | 446 | /* First pass: look for a config entry that looks normal. |
447 | * Two tries: without IO aliases, then with aliases */ | 447 | * Two tries: without IO aliases, then with aliases */ |
448 | link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_SET_IO; | 448 | link->config_flags |= CONF_AUTO_SET_VPP; |
449 | for (try = 0; try < 4; try++) | 449 | for (try = 0; try < 4; try++) |
450 | if (!pcmcia_loop_config(link, simple_config_check, &try)) | 450 | if (!pcmcia_loop_config(link, simple_config_check, &try)) |
451 | goto found_port; | 451 | goto found_port; |
@@ -501,7 +501,8 @@ static int multi_config_check_notpicky(struct pcmcia_device *p_dev, | |||
501 | { | 501 | { |
502 | int *base2 = priv_data; | 502 | int *base2 = priv_data; |
503 | 503 | ||
504 | if (!p_dev->resource[0]->end || !p_dev->resource[1]->end) | 504 | if (!p_dev->resource[0]->end || !p_dev->resource[1]->end || |
505 | p_dev->resource[0]->start + 8 != p_dev->resource[1]->start) | ||
505 | return -ENODEV; | 506 | return -ENODEV; |
506 | 507 | ||
507 | p_dev->resource[0]->end = p_dev->resource[1]->end = 8; | 508 | p_dev->resource[0]->end = p_dev->resource[1]->end = 8; |
@@ -520,7 +521,6 @@ static int multi_config(struct pcmcia_device *link) | |||
520 | struct serial_info *info = link->priv; | 521 | struct serial_info *info = link->priv; |
521 | int i, base2 = 0; | 522 | int i, base2 = 0; |
522 | 523 | ||
523 | link->config_flags |= CONF_AUTO_SET_IO; | ||
524 | /* First, look for a generic full-sized window */ | 524 | /* First, look for a generic full-sized window */ |
525 | if (!pcmcia_loop_config(link, multi_config_check, &info->multi)) | 525 | if (!pcmcia_loop_config(link, multi_config_check, &info->multi)) |
526 | base2 = link->resource[0]->start + 8; | 526 | base2 = link->resource[0]->start + 8; |
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c new file mode 100644 index 000000000000..a60523fee11b --- /dev/null +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -0,0 +1,783 @@ | |||
1 | /* | ||
2 | * Driver for CSR SiRFprimaII onboard UARTs. | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/ioport.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/sysrq.h> | ||
14 | #include <linux/console.h> | ||
15 | #include <linux/tty.h> | ||
16 | #include <linux/tty_flip.h> | ||
17 | #include <linux/serial_core.h> | ||
18 | #include <linux/serial.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <asm/irq.h> | ||
24 | #include <asm/mach/irq.h> | ||
25 | #include <linux/pinctrl/pinmux.h> | ||
26 | |||
27 | #include "sirfsoc_uart.h" | ||
28 | |||
29 | static unsigned int | ||
30 | sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count); | ||
31 | static unsigned int | ||
32 | sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count); | ||
33 | static struct uart_driver sirfsoc_uart_drv; | ||
34 | |||
35 | static const struct sirfsoc_baudrate_to_regv baudrate_to_regv[] = { | ||
36 | {4000000, 2359296}, | ||
37 | {3500000, 1310721}, | ||
38 | {3000000, 1572865}, | ||
39 | {2500000, 1245186}, | ||
40 | {2000000, 1572866}, | ||
41 | {1500000, 1245188}, | ||
42 | {1152000, 1638404}, | ||
43 | {1000000, 1572869}, | ||
44 | {921600, 1114120}, | ||
45 | {576000, 1245196}, | ||
46 | {500000, 1245198}, | ||
47 | {460800, 1572876}, | ||
48 | {230400, 1310750}, | ||
49 | {115200, 1310781}, | ||
50 | {57600, 1310843}, | ||
51 | {38400, 1114328}, | ||
52 | {19200, 1114545}, | ||
53 | {9600, 1114979}, | ||
54 | }; | ||
55 | |||
56 | static struct sirfsoc_uart_port sirfsoc_uart_ports[SIRFSOC_UART_NR] = { | ||
57 | [0] = { | ||
58 | .port = { | ||
59 | .iotype = UPIO_MEM, | ||
60 | .flags = UPF_BOOT_AUTOCONF, | ||
61 | .line = 0, | ||
62 | }, | ||
63 | }, | ||
64 | [1] = { | ||
65 | .port = { | ||
66 | .iotype = UPIO_MEM, | ||
67 | .flags = UPF_BOOT_AUTOCONF, | ||
68 | .line = 1, | ||
69 | }, | ||
70 | }, | ||
71 | [2] = { | ||
72 | .port = { | ||
73 | .iotype = UPIO_MEM, | ||
74 | .flags = UPF_BOOT_AUTOCONF, | ||
75 | .line = 2, | ||
76 | }, | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) | ||
81 | { | ||
82 | return container_of(port, struct sirfsoc_uart_port, port); | ||
83 | } | ||
84 | |||
85 | static inline unsigned int sirfsoc_uart_tx_empty(struct uart_port *port) | ||
86 | { | ||
87 | unsigned long reg; | ||
88 | reg = rd_regl(port, SIRFUART_TX_FIFO_STATUS); | ||
89 | if (reg & SIRFUART_FIFOEMPTY_MASK(port)) | ||
90 | return TIOCSER_TEMT; | ||
91 | else | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static unsigned int sirfsoc_uart_get_mctrl(struct uart_port *port) | ||
96 | { | ||
97 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
98 | if (!(sirfport->ms_enabled)) { | ||
99 | goto cts_asserted; | ||
100 | } else if (sirfport->hw_flow_ctrl) { | ||
101 | if (!(rd_regl(port, SIRFUART_AFC_CTRL) & | ||
102 | SIRFUART_CTS_IN_STATUS)) | ||
103 | goto cts_asserted; | ||
104 | else | ||
105 | goto cts_deasserted; | ||
106 | } | ||
107 | cts_deasserted: | ||
108 | return TIOCM_CAR | TIOCM_DSR; | ||
109 | cts_asserted: | ||
110 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
111 | } | ||
112 | |||
113 | static void sirfsoc_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
114 | { | ||
115 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
116 | unsigned int assert = mctrl & TIOCM_RTS; | ||
117 | unsigned int val = assert ? SIRFUART_AFC_CTRL_RX_THD : 0x0; | ||
118 | unsigned int current_val; | ||
119 | if (sirfport->hw_flow_ctrl) { | ||
120 | current_val = rd_regl(port, SIRFUART_AFC_CTRL) & ~0xFF; | ||
121 | val |= current_val; | ||
122 | wr_regl(port, SIRFUART_AFC_CTRL, val); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static void sirfsoc_uart_stop_tx(struct uart_port *port) | ||
127 | { | ||
128 | unsigned int regv; | ||
129 | regv = rd_regl(port, SIRFUART_INT_EN); | ||
130 | wr_regl(port, SIRFUART_INT_EN, regv & ~SIRFUART_TX_INT_EN); | ||
131 | } | ||
132 | |||
133 | void sirfsoc_uart_start_tx(struct uart_port *port) | ||
134 | { | ||
135 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
136 | unsigned long regv; | ||
137 | sirfsoc_uart_pio_tx_chars(sirfport, 1); | ||
138 | wr_regl(port, SIRFUART_TX_FIFO_OP, SIRFUART_TX_FIFO_START); | ||
139 | regv = rd_regl(port, SIRFUART_INT_EN); | ||
140 | wr_regl(port, SIRFUART_INT_EN, regv | SIRFUART_TX_INT_EN); | ||
141 | } | ||
142 | |||
143 | static void sirfsoc_uart_stop_rx(struct uart_port *port) | ||
144 | { | ||
145 | unsigned long regv; | ||
146 | wr_regl(port, SIRFUART_RX_FIFO_OP, 0); | ||
147 | regv = rd_regl(port, SIRFUART_INT_EN); | ||
148 | wr_regl(port, SIRFUART_INT_EN, regv & ~SIRFUART_RX_IO_INT_EN); | ||
149 | } | ||
150 | |||
151 | static void sirfsoc_uart_disable_ms(struct uart_port *port) | ||
152 | { | ||
153 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
154 | unsigned long reg; | ||
155 | sirfport->ms_enabled = 0; | ||
156 | if (!sirfport->hw_flow_ctrl) | ||
157 | return; | ||
158 | reg = rd_regl(port, SIRFUART_AFC_CTRL); | ||
159 | wr_regl(port, SIRFUART_AFC_CTRL, reg & ~0x3FF); | ||
160 | reg = rd_regl(port, SIRFUART_INT_EN); | ||
161 | wr_regl(port, SIRFUART_INT_EN, reg & ~SIRFUART_CTS_INT_EN); | ||
162 | } | ||
163 | |||
164 | static void sirfsoc_uart_enable_ms(struct uart_port *port) | ||
165 | { | ||
166 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
167 | unsigned long reg; | ||
168 | unsigned long flg; | ||
169 | if (!sirfport->hw_flow_ctrl) | ||
170 | return; | ||
171 | flg = SIRFUART_AFC_RX_EN | SIRFUART_AFC_TX_EN; | ||
172 | reg = rd_regl(port, SIRFUART_AFC_CTRL); | ||
173 | wr_regl(port, SIRFUART_AFC_CTRL, reg | flg); | ||
174 | reg = rd_regl(port, SIRFUART_INT_EN); | ||
175 | wr_regl(port, SIRFUART_INT_EN, reg | SIRFUART_CTS_INT_EN); | ||
176 | uart_handle_cts_change(port, | ||
177 | !(rd_regl(port, SIRFUART_AFC_CTRL) & SIRFUART_CTS_IN_STATUS)); | ||
178 | sirfport->ms_enabled = 1; | ||
179 | } | ||
180 | |||
181 | static void sirfsoc_uart_break_ctl(struct uart_port *port, int break_state) | ||
182 | { | ||
183 | unsigned long ulcon = rd_regl(port, SIRFUART_LINE_CTRL); | ||
184 | if (break_state) | ||
185 | ulcon |= SIRFUART_SET_BREAK; | ||
186 | else | ||
187 | ulcon &= ~SIRFUART_SET_BREAK; | ||
188 | wr_regl(port, SIRFUART_LINE_CTRL, ulcon); | ||
189 | } | ||
190 | |||
191 | static unsigned int | ||
192 | sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | ||
193 | { | ||
194 | 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 | |||
201 | while (!(rd_regl(port, SIRFUART_RX_FIFO_STATUS) & | ||
202 | SIRFUART_FIFOEMPTY_MASK(port))) { | ||
203 | ch = rd_regl(port, SIRFUART_RX_FIFO_DATA) | SIRFUART_DUMMY_READ; | ||
204 | if (unlikely(uart_handle_sysrq_char(port, ch))) | ||
205 | continue; | ||
206 | uart_insert_char(port, 0, 0, ch, TTY_NORMAL); | ||
207 | rx_count++; | ||
208 | if (rx_count >= max_rx_count) | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | port->icount.rx += rx_count; | ||
213 | tty_flip_buffer_push(tty); | ||
214 | tty_kref_put(tty); | ||
215 | |||
216 | return rx_count; | ||
217 | } | ||
218 | |||
219 | static unsigned int | ||
220 | sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count) | ||
221 | { | ||
222 | struct uart_port *port = &sirfport->port; | ||
223 | struct circ_buf *xmit = &port->state->xmit; | ||
224 | unsigned int num_tx = 0; | ||
225 | while (!uart_circ_empty(xmit) && | ||
226 | !(rd_regl(port, SIRFUART_TX_FIFO_STATUS) & | ||
227 | SIRFUART_FIFOFULL_MASK(port)) && | ||
228 | count--) { | ||
229 | wr_regl(port, SIRFUART_TX_FIFO_DATA, xmit->buf[xmit->tail]); | ||
230 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
231 | port->icount.tx++; | ||
232 | num_tx++; | ||
233 | } | ||
234 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
235 | uart_write_wakeup(port); | ||
236 | return num_tx; | ||
237 | } | ||
238 | |||
239 | static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | ||
240 | { | ||
241 | unsigned long intr_status; | ||
242 | unsigned long cts_status; | ||
243 | unsigned long flag = TTY_NORMAL; | ||
244 | struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)dev_id; | ||
245 | struct uart_port *port = &sirfport->port; | ||
246 | struct uart_state *state = port->state; | ||
247 | struct circ_buf *xmit = &port->state->xmit; | ||
248 | intr_status = rd_regl(port, SIRFUART_INT_STATUS); | ||
249 | wr_regl(port, SIRFUART_INT_STATUS, intr_status); | ||
250 | intr_status &= rd_regl(port, SIRFUART_INT_EN); | ||
251 | if (unlikely(intr_status & (SIRFUART_ERR_INT_STAT))) { | ||
252 | if (intr_status & SIRFUART_RXD_BREAK) { | ||
253 | if (uart_handle_break(port)) | ||
254 | goto recv_char; | ||
255 | uart_insert_char(port, intr_status, | ||
256 | SIRFUART_RX_OFLOW, 0, TTY_BREAK); | ||
257 | return IRQ_HANDLED; | ||
258 | } | ||
259 | if (intr_status & SIRFUART_RX_OFLOW) | ||
260 | port->icount.overrun++; | ||
261 | if (intr_status & SIRFUART_FRM_ERR) { | ||
262 | port->icount.frame++; | ||
263 | flag = TTY_FRAME; | ||
264 | } | ||
265 | if (intr_status & SIRFUART_PARITY_ERR) | ||
266 | flag = TTY_PARITY; | ||
267 | wr_regl(port, SIRFUART_RX_FIFO_OP, SIRFUART_RX_FIFO_RESET); | ||
268 | wr_regl(port, SIRFUART_RX_FIFO_OP, 0); | ||
269 | wr_regl(port, SIRFUART_RX_FIFO_OP, SIRFUART_RX_FIFO_START); | ||
270 | intr_status &= port->read_status_mask; | ||
271 | uart_insert_char(port, intr_status, | ||
272 | SIRFUART_RX_OFLOW_INT, 0, flag); | ||
273 | } | ||
274 | recv_char: | ||
275 | if (intr_status & SIRFUART_CTS_INT_EN) { | ||
276 | cts_status = !(rd_regl(port, SIRFUART_AFC_CTRL) & | ||
277 | SIRFUART_CTS_IN_STATUS); | ||
278 | if (cts_status != 0) { | ||
279 | uart_handle_cts_change(port, 1); | ||
280 | } else { | ||
281 | uart_handle_cts_change(port, 0); | ||
282 | wake_up_interruptible(&state->port.delta_msr_wait); | ||
283 | } | ||
284 | } | ||
285 | if (intr_status & SIRFUART_RX_IO_INT_EN) | ||
286 | sirfsoc_uart_pio_rx_chars(port, SIRFSOC_UART_IO_RX_MAX_CNT); | ||
287 | if (intr_status & SIRFUART_TX_INT_EN) { | ||
288 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
289 | return IRQ_HANDLED; | ||
290 | } else { | ||
291 | sirfsoc_uart_pio_tx_chars(sirfport, | ||
292 | SIRFSOC_UART_IO_TX_REASONABLE_CNT); | ||
293 | if ((uart_circ_empty(xmit)) && | ||
294 | (rd_regl(port, SIRFUART_TX_FIFO_STATUS) & | ||
295 | SIRFUART_FIFOEMPTY_MASK(port))) | ||
296 | sirfsoc_uart_stop_tx(port); | ||
297 | } | ||
298 | } | ||
299 | return IRQ_HANDLED; | ||
300 | } | ||
301 | |||
302 | static void sirfsoc_uart_start_rx(struct uart_port *port) | ||
303 | { | ||
304 | unsigned long regv; | ||
305 | regv = rd_regl(port, SIRFUART_INT_EN); | ||
306 | wr_regl(port, SIRFUART_INT_EN, regv | SIRFUART_RX_IO_INT_EN); | ||
307 | wr_regl(port, SIRFUART_RX_FIFO_OP, SIRFUART_RX_FIFO_RESET); | ||
308 | wr_regl(port, SIRFUART_RX_FIFO_OP, 0); | ||
309 | wr_regl(port, SIRFUART_RX_FIFO_OP, SIRFUART_RX_FIFO_START); | ||
310 | } | ||
311 | |||
312 | static unsigned int | ||
313 | sirfsoc_calc_sample_div(unsigned long baud_rate, | ||
314 | unsigned long ioclk_rate, unsigned long *setted_baud) | ||
315 | { | ||
316 | unsigned long min_delta = ~0UL; | ||
317 | unsigned short sample_div; | ||
318 | unsigned int regv = 0; | ||
319 | unsigned long ioclk_div; | ||
320 | unsigned long baud_tmp; | ||
321 | int temp_delta; | ||
322 | |||
323 | for (sample_div = SIRF_MIN_SAMPLE_DIV; | ||
324 | sample_div <= SIRF_MAX_SAMPLE_DIV; sample_div++) { | ||
325 | ioclk_div = (ioclk_rate / (baud_rate * (sample_div + 1))) - 1; | ||
326 | if (ioclk_div > SIRF_IOCLK_DIV_MAX) | ||
327 | continue; | ||
328 | baud_tmp = ioclk_rate / ((ioclk_div + 1) * (sample_div + 1)); | ||
329 | temp_delta = baud_tmp - baud_rate; | ||
330 | temp_delta = (temp_delta > 0) ? temp_delta : -temp_delta; | ||
331 | if (temp_delta < min_delta) { | ||
332 | regv = regv & (~SIRF_IOCLK_DIV_MASK); | ||
333 | regv = regv | ioclk_div; | ||
334 | regv = regv & (~SIRF_SAMPLE_DIV_MASK); | ||
335 | regv = regv | (sample_div << SIRF_SAMPLE_DIV_SHIFT); | ||
336 | min_delta = temp_delta; | ||
337 | *setted_baud = baud_tmp; | ||
338 | } | ||
339 | } | ||
340 | return regv; | ||
341 | } | ||
342 | |||
343 | static void sirfsoc_uart_set_termios(struct uart_port *port, | ||
344 | struct ktermios *termios, | ||
345 | struct ktermios *old) | ||
346 | { | ||
347 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
348 | unsigned long ioclk_rate; | ||
349 | unsigned long config_reg = 0; | ||
350 | unsigned long baud_rate; | ||
351 | unsigned long setted_baud; | ||
352 | unsigned long flags; | ||
353 | unsigned long ic; | ||
354 | unsigned int clk_div_reg = 0; | ||
355 | unsigned long temp_reg_val; | ||
356 | unsigned long rx_time_out; | ||
357 | int threshold_div; | ||
358 | int temp; | ||
359 | |||
360 | ioclk_rate = 150000000; | ||
361 | switch (termios->c_cflag & CSIZE) { | ||
362 | default: | ||
363 | case CS8: | ||
364 | config_reg |= SIRFUART_DATA_BIT_LEN_8; | ||
365 | break; | ||
366 | case CS7: | ||
367 | config_reg |= SIRFUART_DATA_BIT_LEN_7; | ||
368 | break; | ||
369 | case CS6: | ||
370 | config_reg |= SIRFUART_DATA_BIT_LEN_6; | ||
371 | break; | ||
372 | case CS5: | ||
373 | config_reg |= SIRFUART_DATA_BIT_LEN_5; | ||
374 | break; | ||
375 | } | ||
376 | if (termios->c_cflag & CSTOPB) | ||
377 | config_reg |= SIRFUART_STOP_BIT_LEN_2; | ||
378 | baud_rate = uart_get_baud_rate(port, termios, old, 0, 4000000); | ||
379 | spin_lock_irqsave(&port->lock, flags); | ||
380 | port->read_status_mask = SIRFUART_RX_OFLOW_INT; | ||
381 | port->ignore_status_mask = 0; | ||
382 | /* read flags */ | ||
383 | if (termios->c_iflag & INPCK) | ||
384 | port->read_status_mask |= | ||
385 | SIRFUART_FRM_ERR_INT | SIRFUART_PARITY_ERR_INT; | ||
386 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
387 | port->read_status_mask |= SIRFUART_RXD_BREAK_INT; | ||
388 | /* ignore flags */ | ||
389 | if (termios->c_iflag & IGNPAR) | ||
390 | port->ignore_status_mask |= | ||
391 | SIRFUART_FRM_ERR_INT | SIRFUART_PARITY_ERR_INT; | ||
392 | if ((termios->c_cflag & CREAD) == 0) | ||
393 | port->ignore_status_mask |= SIRFUART_DUMMY_READ; | ||
394 | /* enable parity if PARENB is set*/ | ||
395 | if (termios->c_cflag & PARENB) { | ||
396 | if (termios->c_cflag & CMSPAR) { | ||
397 | if (termios->c_cflag & PARODD) | ||
398 | config_reg |= SIRFUART_STICK_BIT_MARK; | ||
399 | else | ||
400 | config_reg |= SIRFUART_STICK_BIT_SPACE; | ||
401 | } else if (termios->c_cflag & PARODD) { | ||
402 | config_reg |= SIRFUART_STICK_BIT_ODD; | ||
403 | } else { | ||
404 | config_reg |= SIRFUART_STICK_BIT_EVEN; | ||
405 | } | ||
406 | } | ||
407 | /* Hardware Flow Control Settings */ | ||
408 | if (UART_ENABLE_MS(port, termios->c_cflag)) { | ||
409 | if (!sirfport->ms_enabled) | ||
410 | sirfsoc_uart_enable_ms(port); | ||
411 | } else { | ||
412 | if (sirfport->ms_enabled) | ||
413 | sirfsoc_uart_disable_ms(port); | ||
414 | } | ||
415 | |||
416 | /* common rate: fast calculation */ | ||
417 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) | ||
418 | if (baud_rate == baudrate_to_regv[ic].baud_rate) | ||
419 | clk_div_reg = baudrate_to_regv[ic].reg_val; | ||
420 | setted_baud = baud_rate; | ||
421 | /* arbitary rate setting */ | ||
422 | if (unlikely(clk_div_reg == 0)) | ||
423 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate, | ||
424 | &setted_baud); | ||
425 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); | ||
426 | |||
427 | if (tty_termios_baud_rate(termios)) | ||
428 | tty_termios_encode_baud_rate(termios, setted_baud, setted_baud); | ||
429 | |||
430 | /* set receive timeout */ | ||
431 | rx_time_out = SIRFSOC_UART_RX_TIMEOUT(baud_rate, 20000); | ||
432 | rx_time_out = (rx_time_out > 0xFFFF) ? 0xFFFF : rx_time_out; | ||
433 | config_reg |= SIRFUART_RECV_TIMEOUT(rx_time_out); | ||
434 | temp_reg_val = rd_regl(port, SIRFUART_TX_FIFO_OP); | ||
435 | wr_regl(port, SIRFUART_RX_FIFO_OP, 0); | ||
436 | wr_regl(port, SIRFUART_TX_FIFO_OP, | ||
437 | temp_reg_val & ~SIRFUART_TX_FIFO_START); | ||
438 | wr_regl(port, SIRFUART_TX_DMA_IO_CTRL, SIRFUART_TX_MODE_IO); | ||
439 | wr_regl(port, SIRFUART_RX_DMA_IO_CTRL, SIRFUART_RX_MODE_IO); | ||
440 | wr_regl(port, SIRFUART_LINE_CTRL, config_reg); | ||
441 | |||
442 | /* Reset Rx/Tx FIFO Threshold level for proper baudrate */ | ||
443 | if (baud_rate < 1000000) | ||
444 | threshold_div = 1; | ||
445 | else | ||
446 | threshold_div = 2; | ||
447 | temp = port->line == 1 ? 16 : 64; | ||
448 | wr_regl(port, SIRFUART_TX_FIFO_CTRL, temp / threshold_div); | ||
449 | wr_regl(port, SIRFUART_RX_FIFO_CTRL, temp / threshold_div); | ||
450 | temp_reg_val |= SIRFUART_TX_FIFO_START; | ||
451 | wr_regl(port, SIRFUART_TX_FIFO_OP, temp_reg_val); | ||
452 | uart_update_timeout(port, termios->c_cflag, baud_rate); | ||
453 | sirfsoc_uart_start_rx(port); | ||
454 | wr_regl(port, SIRFUART_TX_RX_EN, SIRFUART_TX_EN | SIRFUART_RX_EN); | ||
455 | spin_unlock_irqrestore(&port->lock, flags); | ||
456 | } | ||
457 | |||
458 | static void startup_uart_controller(struct uart_port *port) | ||
459 | { | ||
460 | unsigned long temp_regv; | ||
461 | int temp; | ||
462 | temp_regv = rd_regl(port, SIRFUART_TX_DMA_IO_CTRL); | ||
463 | wr_regl(port, SIRFUART_TX_DMA_IO_CTRL, temp_regv | SIRFUART_TX_MODE_IO); | ||
464 | temp_regv = rd_regl(port, SIRFUART_RX_DMA_IO_CTRL); | ||
465 | wr_regl(port, SIRFUART_RX_DMA_IO_CTRL, temp_regv | SIRFUART_RX_MODE_IO); | ||
466 | wr_regl(port, SIRFUART_TX_DMA_IO_LEN, 0); | ||
467 | wr_regl(port, SIRFUART_RX_DMA_IO_LEN, 0); | ||
468 | wr_regl(port, SIRFUART_TX_RX_EN, SIRFUART_RX_EN | SIRFUART_TX_EN); | ||
469 | wr_regl(port, SIRFUART_TX_FIFO_OP, SIRFUART_TX_FIFO_RESET); | ||
470 | wr_regl(port, SIRFUART_TX_FIFO_OP, 0); | ||
471 | wr_regl(port, SIRFUART_RX_FIFO_OP, SIRFUART_RX_FIFO_RESET); | ||
472 | wr_regl(port, SIRFUART_RX_FIFO_OP, 0); | ||
473 | temp = port->line == 1 ? 16 : 64; | ||
474 | wr_regl(port, SIRFUART_TX_FIFO_CTRL, temp); | ||
475 | wr_regl(port, SIRFUART_RX_FIFO_CTRL, temp); | ||
476 | } | ||
477 | |||
478 | static int sirfsoc_uart_startup(struct uart_port *port) | ||
479 | { | ||
480 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
481 | unsigned int index = port->line; | ||
482 | int ret; | ||
483 | set_irq_flags(port->irq, IRQF_VALID | IRQF_NOAUTOEN); | ||
484 | ret = request_irq(port->irq, | ||
485 | sirfsoc_uart_isr, | ||
486 | 0, | ||
487 | SIRFUART_PORT_NAME, | ||
488 | sirfport); | ||
489 | if (ret != 0) { | ||
490 | dev_err(port->dev, "UART%d request IRQ line (%d) failed.\n", | ||
491 | index, port->irq); | ||
492 | goto irq_err; | ||
493 | } | ||
494 | startup_uart_controller(port); | ||
495 | enable_irq(port->irq); | ||
496 | irq_err: | ||
497 | return ret; | ||
498 | } | ||
499 | |||
500 | static void sirfsoc_uart_shutdown(struct uart_port *port) | ||
501 | { | ||
502 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
503 | wr_regl(port, SIRFUART_INT_EN, 0); | ||
504 | free_irq(port->irq, sirfport); | ||
505 | if (sirfport->ms_enabled) { | ||
506 | sirfsoc_uart_disable_ms(port); | ||
507 | sirfport->ms_enabled = 0; | ||
508 | } | ||
509 | } | ||
510 | |||
511 | static const char *sirfsoc_uart_type(struct uart_port *port) | ||
512 | { | ||
513 | return port->type == SIRFSOC_PORT_TYPE ? SIRFUART_PORT_NAME : NULL; | ||
514 | } | ||
515 | |||
516 | static int sirfsoc_uart_request_port(struct uart_port *port) | ||
517 | { | ||
518 | void *ret; | ||
519 | ret = request_mem_region(port->mapbase, | ||
520 | SIRFUART_MAP_SIZE, SIRFUART_PORT_NAME); | ||
521 | return ret ? 0 : -EBUSY; | ||
522 | } | ||
523 | |||
524 | static void sirfsoc_uart_release_port(struct uart_port *port) | ||
525 | { | ||
526 | release_mem_region(port->mapbase, SIRFUART_MAP_SIZE); | ||
527 | } | ||
528 | |||
529 | static void sirfsoc_uart_config_port(struct uart_port *port, int flags) | ||
530 | { | ||
531 | if (flags & UART_CONFIG_TYPE) { | ||
532 | port->type = SIRFSOC_PORT_TYPE; | ||
533 | sirfsoc_uart_request_port(port); | ||
534 | } | ||
535 | } | ||
536 | |||
537 | static struct uart_ops sirfsoc_uart_ops = { | ||
538 | .tx_empty = sirfsoc_uart_tx_empty, | ||
539 | .get_mctrl = sirfsoc_uart_get_mctrl, | ||
540 | .set_mctrl = sirfsoc_uart_set_mctrl, | ||
541 | .stop_tx = sirfsoc_uart_stop_tx, | ||
542 | .start_tx = sirfsoc_uart_start_tx, | ||
543 | .stop_rx = sirfsoc_uart_stop_rx, | ||
544 | .enable_ms = sirfsoc_uart_enable_ms, | ||
545 | .break_ctl = sirfsoc_uart_break_ctl, | ||
546 | .startup = sirfsoc_uart_startup, | ||
547 | .shutdown = sirfsoc_uart_shutdown, | ||
548 | .set_termios = sirfsoc_uart_set_termios, | ||
549 | .type = sirfsoc_uart_type, | ||
550 | .release_port = sirfsoc_uart_release_port, | ||
551 | .request_port = sirfsoc_uart_request_port, | ||
552 | .config_port = sirfsoc_uart_config_port, | ||
553 | }; | ||
554 | |||
555 | #ifdef CONFIG_SERIAL_SIRFSOC_CONSOLE | ||
556 | static int __init sirfsoc_uart_console_setup(struct console *co, char *options) | ||
557 | { | ||
558 | unsigned int baud = 115200; | ||
559 | unsigned int bits = 8; | ||
560 | unsigned int parity = 'n'; | ||
561 | unsigned int flow = 'n'; | ||
562 | struct uart_port *port = &sirfsoc_uart_ports[co->index].port; | ||
563 | |||
564 | if (co->index < 0 || co->index >= SIRFSOC_UART_NR) | ||
565 | return -EINVAL; | ||
566 | |||
567 | if (!port->mapbase) | ||
568 | return -ENODEV; | ||
569 | |||
570 | if (options) | ||
571 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
572 | port->cons = co; | ||
573 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
574 | } | ||
575 | |||
576 | static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch) | ||
577 | { | ||
578 | while (rd_regl(port, | ||
579 | SIRFUART_TX_FIFO_STATUS) & SIRFUART_FIFOFULL_MASK(port)) | ||
580 | cpu_relax(); | ||
581 | wr_regb(port, SIRFUART_TX_FIFO_DATA, ch); | ||
582 | } | ||
583 | |||
584 | static void sirfsoc_uart_console_write(struct console *co, const char *s, | ||
585 | unsigned int count) | ||
586 | { | ||
587 | struct uart_port *port = &sirfsoc_uart_ports[co->index].port; | ||
588 | uart_console_write(port, s, count, sirfsoc_uart_console_putchar); | ||
589 | } | ||
590 | |||
591 | static struct console sirfsoc_uart_console = { | ||
592 | .name = SIRFSOC_UART_NAME, | ||
593 | .device = uart_console_device, | ||
594 | .flags = CON_PRINTBUFFER, | ||
595 | .index = -1, | ||
596 | .write = sirfsoc_uart_console_write, | ||
597 | .setup = sirfsoc_uart_console_setup, | ||
598 | .data = &sirfsoc_uart_drv, | ||
599 | }; | ||
600 | |||
601 | static int __init sirfsoc_uart_console_init(void) | ||
602 | { | ||
603 | register_console(&sirfsoc_uart_console); | ||
604 | return 0; | ||
605 | } | ||
606 | console_initcall(sirfsoc_uart_console_init); | ||
607 | #endif | ||
608 | |||
609 | static struct uart_driver sirfsoc_uart_drv = { | ||
610 | .owner = THIS_MODULE, | ||
611 | .driver_name = SIRFUART_PORT_NAME, | ||
612 | .nr = SIRFSOC_UART_NR, | ||
613 | .dev_name = SIRFSOC_UART_NAME, | ||
614 | .major = SIRFSOC_UART_MAJOR, | ||
615 | .minor = SIRFSOC_UART_MINOR, | ||
616 | #ifdef CONFIG_SERIAL_SIRFSOC_CONSOLE | ||
617 | .cons = &sirfsoc_uart_console, | ||
618 | #else | ||
619 | .cons = NULL, | ||
620 | #endif | ||
621 | }; | ||
622 | |||
623 | int sirfsoc_uart_probe(struct platform_device *pdev) | ||
624 | { | ||
625 | struct sirfsoc_uart_port *sirfport; | ||
626 | struct uart_port *port; | ||
627 | struct resource *res; | ||
628 | int ret; | ||
629 | |||
630 | if (of_property_read_u32(pdev->dev.of_node, "cell-index", &pdev->id)) { | ||
631 | dev_err(&pdev->dev, | ||
632 | "Unable to find cell-index in uart node.\n"); | ||
633 | ret = -EFAULT; | ||
634 | goto err; | ||
635 | } | ||
636 | |||
637 | sirfport = &sirfsoc_uart_ports[pdev->id]; | ||
638 | port = &sirfport->port; | ||
639 | port->dev = &pdev->dev; | ||
640 | port->private_data = sirfport; | ||
641 | |||
642 | if (of_find_property(pdev->dev.of_node, "hw_flow_ctrl", NULL)) | ||
643 | sirfport->hw_flow_ctrl = 1; | ||
644 | |||
645 | if (of_property_read_u32(pdev->dev.of_node, | ||
646 | "fifosize", | ||
647 | &port->fifosize)) { | ||
648 | dev_err(&pdev->dev, | ||
649 | "Unable to find fifosize in uart node.\n"); | ||
650 | ret = -EFAULT; | ||
651 | goto err; | ||
652 | } | ||
653 | |||
654 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
655 | if (res == NULL) { | ||
656 | dev_err(&pdev->dev, "Insufficient resources.\n"); | ||
657 | ret = -EFAULT; | ||
658 | goto err; | ||
659 | } | ||
660 | port->mapbase = res->start; | ||
661 | port->membase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||
662 | if (!port->membase) { | ||
663 | dev_err(&pdev->dev, "Cannot remap resource.\n"); | ||
664 | ret = -ENOMEM; | ||
665 | goto err; | ||
666 | } | ||
667 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
668 | if (res == NULL) { | ||
669 | dev_err(&pdev->dev, "Insufficient resources.\n"); | ||
670 | ret = -EFAULT; | ||
671 | goto irq_err; | ||
672 | } | ||
673 | port->irq = res->start; | ||
674 | |||
675 | if (sirfport->hw_flow_ctrl) { | ||
676 | sirfport->pmx = pinmux_get(&pdev->dev, NULL); | ||
677 | ret = IS_ERR(sirfport->pmx); | ||
678 | if (ret) | ||
679 | goto pmx_err; | ||
680 | |||
681 | pinmux_enable(sirfport->pmx); | ||
682 | } | ||
683 | |||
684 | port->ops = &sirfsoc_uart_ops; | ||
685 | spin_lock_init(&port->lock); | ||
686 | |||
687 | platform_set_drvdata(pdev, sirfport); | ||
688 | ret = uart_add_one_port(&sirfsoc_uart_drv, port); | ||
689 | if (ret != 0) { | ||
690 | dev_err(&pdev->dev, "Cannot add UART port(%d).\n", pdev->id); | ||
691 | goto port_err; | ||
692 | } | ||
693 | |||
694 | return 0; | ||
695 | |||
696 | port_err: | ||
697 | platform_set_drvdata(pdev, NULL); | ||
698 | if (sirfport->hw_flow_ctrl) { | ||
699 | pinmux_disable(sirfport->pmx); | ||
700 | pinmux_put(sirfport->pmx); | ||
701 | } | ||
702 | pmx_err: | ||
703 | irq_err: | ||
704 | devm_iounmap(&pdev->dev, port->membase); | ||
705 | err: | ||
706 | return ret; | ||
707 | } | ||
708 | |||
709 | static int sirfsoc_uart_remove(struct platform_device *pdev) | ||
710 | { | ||
711 | struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); | ||
712 | struct uart_port *port = &sirfport->port; | ||
713 | platform_set_drvdata(pdev, NULL); | ||
714 | if (sirfport->hw_flow_ctrl) { | ||
715 | pinmux_disable(sirfport->pmx); | ||
716 | pinmux_put(sirfport->pmx); | ||
717 | } | ||
718 | devm_iounmap(&pdev->dev, port->membase); | ||
719 | uart_remove_one_port(&sirfsoc_uart_drv, port); | ||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static int | ||
724 | sirfsoc_uart_suspend(struct platform_device *pdev, pm_message_t state) | ||
725 | { | ||
726 | struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); | ||
727 | struct uart_port *port = &sirfport->port; | ||
728 | uart_suspend_port(&sirfsoc_uart_drv, port); | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | static int sirfsoc_uart_resume(struct platform_device *pdev) | ||
733 | { | ||
734 | struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); | ||
735 | struct uart_port *port = &sirfport->port; | ||
736 | uart_resume_port(&sirfsoc_uart_drv, port); | ||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | static struct of_device_id sirfsoc_uart_ids[] __devinitdata = { | ||
741 | { .compatible = "sirf,prima2-uart", }, | ||
742 | {} | ||
743 | }; | ||
744 | MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); | ||
745 | |||
746 | static struct platform_driver sirfsoc_uart_driver = { | ||
747 | .probe = sirfsoc_uart_probe, | ||
748 | .remove = __devexit_p(sirfsoc_uart_remove), | ||
749 | .suspend = sirfsoc_uart_suspend, | ||
750 | .resume = sirfsoc_uart_resume, | ||
751 | .driver = { | ||
752 | .name = SIRFUART_PORT_NAME, | ||
753 | .owner = THIS_MODULE, | ||
754 | .of_match_table = sirfsoc_uart_ids, | ||
755 | }, | ||
756 | }; | ||
757 | |||
758 | static int __init sirfsoc_uart_init(void) | ||
759 | { | ||
760 | int ret = 0; | ||
761 | |||
762 | ret = uart_register_driver(&sirfsoc_uart_drv); | ||
763 | if (ret) | ||
764 | goto out; | ||
765 | |||
766 | ret = platform_driver_register(&sirfsoc_uart_driver); | ||
767 | if (ret) | ||
768 | uart_unregister_driver(&sirfsoc_uart_drv); | ||
769 | out: | ||
770 | return ret; | ||
771 | } | ||
772 | module_init(sirfsoc_uart_init); | ||
773 | |||
774 | static void __exit sirfsoc_uart_exit(void) | ||
775 | { | ||
776 | platform_driver_unregister(&sirfsoc_uart_driver); | ||
777 | uart_unregister_driver(&sirfsoc_uart_drv); | ||
778 | } | ||
779 | module_exit(sirfsoc_uart_exit); | ||
780 | |||
781 | MODULE_LICENSE("GPL v2"); | ||
782 | MODULE_AUTHOR("Bin Shi <Bin.Shi@csr.com>, Rong Wang<Rong.Wang@csr.com>"); | ||
783 | MODULE_DESCRIPTION("CSR SiRFprimaII Uart Driver"); | ||
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h new file mode 100644 index 000000000000..fc64260fa93c --- /dev/null +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -0,0 +1,185 @@ | |||
1 | /* | ||
2 | * Drivers for CSR SiRFprimaII onboard UARTs. | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | #include <linux/bitops.h> | ||
9 | |||
10 | /* UART Register Offset Define */ | ||
11 | #define SIRFUART_LINE_CTRL 0x0040 | ||
12 | #define SIRFUART_TX_RX_EN 0x004c | ||
13 | #define SIRFUART_DIVISOR 0x0050 | ||
14 | #define SIRFUART_INT_EN 0x0054 | ||
15 | #define SIRFUART_INT_STATUS 0x0058 | ||
16 | #define SIRFUART_TX_DMA_IO_CTRL 0x0100 | ||
17 | #define SIRFUART_TX_DMA_IO_LEN 0x0104 | ||
18 | #define SIRFUART_TX_FIFO_CTRL 0x0108 | ||
19 | #define SIRFUART_TX_FIFO_LEVEL_CHK 0x010C | ||
20 | #define SIRFUART_TX_FIFO_OP 0x0110 | ||
21 | #define SIRFUART_TX_FIFO_STATUS 0x0114 | ||
22 | #define SIRFUART_TX_FIFO_DATA 0x0118 | ||
23 | #define SIRFUART_RX_DMA_IO_CTRL 0x0120 | ||
24 | #define SIRFUART_RX_DMA_IO_LEN 0x0124 | ||
25 | #define SIRFUART_RX_FIFO_CTRL 0x0128 | ||
26 | #define SIRFUART_RX_FIFO_LEVEL_CHK 0x012C | ||
27 | #define SIRFUART_RX_FIFO_OP 0x0130 | ||
28 | #define SIRFUART_RX_FIFO_STATUS 0x0134 | ||
29 | #define SIRFUART_RX_FIFO_DATA 0x0138 | ||
30 | #define SIRFUART_AFC_CTRL 0x0140 | ||
31 | #define SIRFUART_SWH_DMA_IO 0x0148 | ||
32 | |||
33 | /* UART Line Control Register */ | ||
34 | #define SIRFUART_DATA_BIT_LEN_MASK 0x3 | ||
35 | #define SIRFUART_DATA_BIT_LEN_5 BIT(0) | ||
36 | #define SIRFUART_DATA_BIT_LEN_6 1 | ||
37 | #define SIRFUART_DATA_BIT_LEN_7 2 | ||
38 | #define SIRFUART_DATA_BIT_LEN_8 3 | ||
39 | #define SIRFUART_STOP_BIT_LEN_1 0 | ||
40 | #define SIRFUART_STOP_BIT_LEN_2 BIT(2) | ||
41 | #define SIRFUART_PARITY_EN BIT(3) | ||
42 | #define SIRFUART_EVEN_BIT BIT(4) | ||
43 | #define SIRFUART_STICK_BIT_MASK (7 << 3) | ||
44 | #define SIRFUART_STICK_BIT_NONE (0 << 3) | ||
45 | #define SIRFUART_STICK_BIT_EVEN BIT(3) | ||
46 | #define SIRFUART_STICK_BIT_ODD (3 << 3) | ||
47 | #define SIRFUART_STICK_BIT_MARK (5 << 3) | ||
48 | #define SIRFUART_STICK_BIT_SPACE (7 << 3) | ||
49 | #define SIRFUART_SET_BREAK BIT(6) | ||
50 | #define SIRFUART_LOOP_BACK BIT(7) | ||
51 | #define SIRFUART_PARITY_MASK (7 << 3) | ||
52 | #define SIRFUART_DUMMY_READ BIT(16) | ||
53 | |||
54 | #define SIRFSOC_UART_RX_TIMEOUT(br, to) (((br) * (((to) + 999) / 1000)) / 1000) | ||
55 | #define SIRFUART_RECV_TIMEOUT_MASK (0xFFFF << 16) | ||
56 | #define SIRFUART_RECV_TIMEOUT(x) (((x) & 0xFFFF) << 16) | ||
57 | |||
58 | /* UART Auto Flow Control */ | ||
59 | #define SIRFUART_AFC_RX_THD_MASK 0x000000FF | ||
60 | #define SIRFUART_AFC_RX_EN BIT(8) | ||
61 | #define SIRFUART_AFC_TX_EN BIT(9) | ||
62 | #define SIRFUART_CTS_CTRL BIT(10) | ||
63 | #define SIRFUART_RTS_CTRL BIT(11) | ||
64 | #define SIRFUART_CTS_IN_STATUS BIT(12) | ||
65 | #define SIRFUART_RTS_OUT_STATUS BIT(13) | ||
66 | |||
67 | /* UART Interrupt Enable Register */ | ||
68 | #define SIRFUART_RX_DONE_INT BIT(0) | ||
69 | #define SIRFUART_TX_DONE_INT BIT(1) | ||
70 | #define SIRFUART_RX_OFLOW_INT BIT(2) | ||
71 | #define SIRFUART_TX_ALLOUT_INT BIT(3) | ||
72 | #define SIRFUART_RX_IO_DMA_INT BIT(4) | ||
73 | #define SIRFUART_TX_IO_DMA_INT BIT(5) | ||
74 | #define SIRFUART_RXFIFO_FULL_INT BIT(6) | ||
75 | #define SIRFUART_TXFIFO_EMPTY_INT BIT(7) | ||
76 | #define SIRFUART_RXFIFO_THD_INT BIT(8) | ||
77 | #define SIRFUART_TXFIFO_THD_INT BIT(9) | ||
78 | #define SIRFUART_FRM_ERR_INT BIT(10) | ||
79 | #define SIRFUART_RXD_BREAK_INT BIT(11) | ||
80 | #define SIRFUART_RX_TIMEOUT_INT BIT(12) | ||
81 | #define SIRFUART_PARITY_ERR_INT BIT(13) | ||
82 | #define SIRFUART_CTS_INT_EN BIT(14) | ||
83 | #define SIRFUART_RTS_INT_EN BIT(15) | ||
84 | |||
85 | /* UART Interrupt Status Register */ | ||
86 | #define SIRFUART_RX_DONE BIT(0) | ||
87 | #define SIRFUART_TX_DONE BIT(1) | ||
88 | #define SIRFUART_RX_OFLOW BIT(2) | ||
89 | #define SIRFUART_TX_ALL_EMPTY BIT(3) | ||
90 | #define SIRFUART_DMA_IO_RX_DONE BIT(4) | ||
91 | #define SIRFUART_DMA_IO_TX_DONE BIT(5) | ||
92 | #define SIRFUART_RXFIFO_FULL BIT(6) | ||
93 | #define SIRFUART_TXFIFO_EMPTY BIT(7) | ||
94 | #define SIRFUART_RXFIFO_THD_REACH BIT(8) | ||
95 | #define SIRFUART_TXFIFO_THD_REACH BIT(9) | ||
96 | #define SIRFUART_FRM_ERR BIT(10) | ||
97 | #define SIRFUART_RXD_BREAK BIT(11) | ||
98 | #define SIRFUART_RX_TIMEOUT BIT(12) | ||
99 | #define SIRFUART_PARITY_ERR BIT(13) | ||
100 | #define SIRFUART_CTS_CHANGE BIT(14) | ||
101 | #define SIRFUART_RTS_CHANGE BIT(15) | ||
102 | #define SIRFUART_PLUG_IN BIT(16) | ||
103 | |||
104 | #define SIRFUART_ERR_INT_STAT \ | ||
105 | (SIRFUART_RX_OFLOW | \ | ||
106 | SIRFUART_FRM_ERR | \ | ||
107 | SIRFUART_RXD_BREAK | \ | ||
108 | SIRFUART_PARITY_ERR) | ||
109 | #define SIRFUART_ERR_INT_EN \ | ||
110 | (SIRFUART_RX_OFLOW_INT | \ | ||
111 | SIRFUART_FRM_ERR_INT | \ | ||
112 | SIRFUART_RXD_BREAK_INT | \ | ||
113 | SIRFUART_PARITY_ERR_INT) | ||
114 | #define SIRFUART_TX_INT_EN SIRFUART_TXFIFO_EMPTY_INT | ||
115 | #define SIRFUART_RX_IO_INT_EN \ | ||
116 | (SIRFUART_RX_TIMEOUT_INT | \ | ||
117 | SIRFUART_RXFIFO_THD_INT | \ | ||
118 | SIRFUART_RXFIFO_FULL_INT | \ | ||
119 | SIRFUART_ERR_INT_EN) | ||
120 | |||
121 | /* UART FIFO Register */ | ||
122 | #define SIRFUART_TX_FIFO_STOP 0x0 | ||
123 | #define SIRFUART_TX_FIFO_RESET 0x1 | ||
124 | #define SIRFUART_TX_FIFO_START 0x2 | ||
125 | #define SIRFUART_RX_FIFO_STOP 0x0 | ||
126 | #define SIRFUART_RX_FIFO_RESET 0x1 | ||
127 | #define SIRFUART_RX_FIFO_START 0x2 | ||
128 | #define SIRFUART_TX_MODE_DMA 0 | ||
129 | #define SIRFUART_TX_MODE_IO 1 | ||
130 | #define SIRFUART_RX_MODE_DMA 0 | ||
131 | #define SIRFUART_RX_MODE_IO 1 | ||
132 | |||
133 | #define SIRFUART_RX_EN 0x1 | ||
134 | #define SIRFUART_TX_EN 0x2 | ||
135 | |||
136 | /* Generic Definitions */ | ||
137 | #define SIRFSOC_UART_NAME "ttySiRF" | ||
138 | #define SIRFSOC_UART_MAJOR 0 | ||
139 | #define SIRFSOC_UART_MINOR 0 | ||
140 | #define SIRFUART_PORT_NAME "sirfsoc-uart" | ||
141 | #define SIRFUART_MAP_SIZE 0x200 | ||
142 | #define SIRFSOC_UART_NR 3 | ||
143 | #define SIRFSOC_PORT_TYPE 0xa5 | ||
144 | |||
145 | /* Baud Rate Calculation */ | ||
146 | #define SIRF_MIN_SAMPLE_DIV 0xf | ||
147 | #define SIRF_MAX_SAMPLE_DIV 0x3f | ||
148 | #define SIRF_IOCLK_DIV_MAX 0xffff | ||
149 | #define SIRF_SAMPLE_DIV_SHIFT 16 | ||
150 | #define SIRF_IOCLK_DIV_MASK 0xffff | ||
151 | #define SIRF_SAMPLE_DIV_MASK 0x3f0000 | ||
152 | #define SIRF_BAUD_RATE_SUPPORT_NR 18 | ||
153 | |||
154 | /* For Fast Baud Rate Calculation */ | ||
155 | struct sirfsoc_baudrate_to_regv { | ||
156 | unsigned int baud_rate; | ||
157 | unsigned int reg_val; | ||
158 | }; | ||
159 | |||
160 | struct sirfsoc_uart_port { | ||
161 | unsigned char hw_flow_ctrl; | ||
162 | unsigned char ms_enabled; | ||
163 | |||
164 | struct uart_port port; | ||
165 | struct pinmux *pmx; | ||
166 | }; | ||
167 | |||
168 | /* Hardware Flow Control */ | ||
169 | #define SIRFUART_AFC_CTRL_RX_THD 0x70 | ||
170 | |||
171 | /* Register Access Control */ | ||
172 | #define portaddr(port, reg) ((port)->membase + (reg)) | ||
173 | #define rd_regb(port, reg) (__raw_readb(portaddr(port, reg))) | ||
174 | #define rd_regl(port, reg) (__raw_readl(portaddr(port, reg))) | ||
175 | #define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg)) | ||
176 | #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) | ||
177 | |||
178 | /* UART Port Mask */ | ||
179 | #define SIRFUART_FIFOLEVEL_MASK(port) ((port->line == 1) ? (0x1f) : (0x7f)) | ||
180 | #define SIRFUART_FIFOFULL_MASK(port) ((port->line == 1) ? (0x20) : (0x80)) | ||
181 | #define SIRFUART_FIFOEMPTY_MASK(port) ((port->line == 1) ? (0x40) : (0x100)) | ||
182 | |||
183 | /* I/O Mode */ | ||
184 | #define SIRFSOC_UART_IO_RX_MAX_CNT 256 | ||
185 | #define SIRFSOC_UART_IO_TX_REASONABLE_CNT 6 | ||
diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index e76c8b747fb8..70f97491d8f2 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c | |||
@@ -513,20 +513,7 @@ static struct platform_driver timbuart_platform_driver = { | |||
513 | .remove = __devexit_p(timbuart_remove), | 513 | .remove = __devexit_p(timbuart_remove), |
514 | }; | 514 | }; |
515 | 515 | ||
516 | /*--------------------------------------------------------------------------*/ | 516 | module_platform_driver(timbuart_platform_driver); |
517 | |||
518 | static int __init timbuart_init(void) | ||
519 | { | ||
520 | return platform_driver_register(&timbuart_platform_driver); | ||
521 | } | ||
522 | |||
523 | static void __exit timbuart_exit(void) | ||
524 | { | ||
525 | platform_driver_unregister(&timbuart_platform_driver); | ||
526 | } | ||
527 | |||
528 | module_init(timbuart_init); | ||
529 | module_exit(timbuart_exit); | ||
530 | 517 | ||
531 | MODULE_DESCRIPTION("Timberdale UART driver"); | 518 | MODULE_DESCRIPTION("Timberdale UART driver"); |
532 | MODULE_LICENSE("GPL v2"); | 519 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 3beb6ab4fa68..83148e79ca13 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c | |||
@@ -961,18 +961,7 @@ static struct platform_driver siu_device_driver = { | |||
961 | }, | 961 | }, |
962 | }; | 962 | }; |
963 | 963 | ||
964 | static int __init vr41xx_siu_init(void) | 964 | module_platform_driver(siu_device_driver); |
965 | { | ||
966 | return platform_driver_register(&siu_device_driver); | ||
967 | } | ||
968 | |||
969 | static void __exit vr41xx_siu_exit(void) | ||
970 | { | ||
971 | platform_driver_unregister(&siu_device_driver); | ||
972 | } | ||
973 | |||
974 | module_init(vr41xx_siu_init); | ||
975 | module_exit(vr41xx_siu_exit); | ||
976 | 965 | ||
977 | MODULE_LICENSE("GPL"); | 966 | MODULE_LICENSE("GPL"); |
978 | MODULE_ALIAS("platform:SIU"); | 967 | MODULE_ALIAS("platform:SIU"); |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3fdebd306b94..e41b9bbc107d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -790,19 +790,24 @@ static void session_clear_tty(struct pid *session) | |||
790 | void disassociate_ctty(int on_exit) | 790 | void disassociate_ctty(int on_exit) |
791 | { | 791 | { |
792 | struct tty_struct *tty; | 792 | struct tty_struct *tty; |
793 | struct pid *tty_pgrp = NULL; | ||
794 | 793 | ||
795 | if (!current->signal->leader) | 794 | if (!current->signal->leader) |
796 | return; | 795 | return; |
797 | 796 | ||
798 | tty = get_current_tty(); | 797 | tty = get_current_tty(); |
799 | if (tty) { | 798 | if (tty) { |
800 | tty_pgrp = get_pid(tty->pgrp); | 799 | struct pid *tty_pgrp = get_pid(tty->pgrp); |
801 | if (on_exit) { | 800 | if (on_exit) { |
802 | if (tty->driver->type != TTY_DRIVER_TYPE_PTY) | 801 | if (tty->driver->type != TTY_DRIVER_TYPE_PTY) |
803 | tty_vhangup(tty); | 802 | tty_vhangup(tty); |
804 | } | 803 | } |
805 | tty_kref_put(tty); | 804 | tty_kref_put(tty); |
805 | if (tty_pgrp) { | ||
806 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); | ||
807 | if (!on_exit) | ||
808 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); | ||
809 | put_pid(tty_pgrp); | ||
810 | } | ||
806 | } else if (on_exit) { | 811 | } else if (on_exit) { |
807 | struct pid *old_pgrp; | 812 | struct pid *old_pgrp; |
808 | spin_lock_irq(¤t->sighand->siglock); | 813 | spin_lock_irq(¤t->sighand->siglock); |
@@ -816,12 +821,6 @@ void disassociate_ctty(int on_exit) | |||
816 | } | 821 | } |
817 | return; | 822 | return; |
818 | } | 823 | } |
819 | if (tty_pgrp) { | ||
820 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); | ||
821 | if (!on_exit) | ||
822 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); | ||
823 | put_pid(tty_pgrp); | ||
824 | } | ||
825 | 824 | ||
826 | spin_lock_irq(¤t->sighand->siglock); | 825 | spin_lock_irq(¤t->sighand->siglock); |
827 | put_pid(current->signal->tty_old_pgrp); | 826 | put_pid(current->signal->tty_old_pgrp); |
@@ -1558,6 +1557,59 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1558 | } | 1557 | } |
1559 | 1558 | ||
1560 | /** | 1559 | /** |
1560 | * tty_release_checks - check a tty before real release | ||
1561 | * @tty: tty to check | ||
1562 | * @o_tty: link of @tty (if any) | ||
1563 | * @idx: index of the tty | ||
1564 | * | ||
1565 | * Performs some paranoid checking before true release of the @tty. | ||
1566 | * This is a no-op unless TTY_PARANOIA_CHECK is defined. | ||
1567 | */ | ||
1568 | static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, | ||
1569 | int idx) | ||
1570 | { | ||
1571 | #ifdef TTY_PARANOIA_CHECK | ||
1572 | if (idx < 0 || idx >= tty->driver->num) { | ||
1573 | printk(KERN_DEBUG "%s: bad idx when trying to free (%s)\n", | ||
1574 | __func__, tty->name); | ||
1575 | return -1; | ||
1576 | } | ||
1577 | |||
1578 | /* not much to check for devpts */ | ||
1579 | if (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) | ||
1580 | return 0; | ||
1581 | |||
1582 | if (tty != tty->driver->ttys[idx]) { | ||
1583 | printk(KERN_DEBUG "%s: driver.table[%d] not tty for (%s)\n", | ||
1584 | __func__, idx, tty->name); | ||
1585 | return -1; | ||
1586 | } | ||
1587 | if (tty->termios != tty->driver->termios[idx]) { | ||
1588 | printk(KERN_DEBUG "%s: driver.termios[%d] not termios for (%s)\n", | ||
1589 | __func__, idx, tty->name); | ||
1590 | return -1; | ||
1591 | } | ||
1592 | if (tty->driver->other) { | ||
1593 | if (o_tty != tty->driver->other->ttys[idx]) { | ||
1594 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", | ||
1595 | __func__, idx, tty->name); | ||
1596 | return -1; | ||
1597 | } | ||
1598 | if (o_tty->termios != tty->driver->other->termios[idx]) { | ||
1599 | printk(KERN_DEBUG "%s: other->termios[%d] not o_termios for (%s)\n", | ||
1600 | __func__, idx, tty->name); | ||
1601 | return -1; | ||
1602 | } | ||
1603 | if (o_tty->link != tty) { | ||
1604 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); | ||
1605 | return -1; | ||
1606 | } | ||
1607 | } | ||
1608 | #endif | ||
1609 | return 0; | ||
1610 | } | ||
1611 | |||
1612 | /** | ||
1561 | * tty_release - vfs callback for close | 1613 | * tty_release - vfs callback for close |
1562 | * @inode: inode of tty | 1614 | * @inode: inode of tty |
1563 | * @filp: file pointer for handle to tty | 1615 | * @filp: file pointer for handle to tty |
@@ -1585,11 +1637,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1585 | int idx; | 1637 | int idx; |
1586 | char buf[64]; | 1638 | char buf[64]; |
1587 | 1639 | ||
1588 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1640 | if (tty_paranoia_check(tty, inode, __func__)) |
1589 | return 0; | 1641 | return 0; |
1590 | 1642 | ||
1591 | tty_lock(); | 1643 | tty_lock(); |
1592 | check_tty_count(tty, "tty_release_dev"); | 1644 | check_tty_count(tty, __func__); |
1593 | 1645 | ||
1594 | __tty_fasync(-1, filp, 0); | 1646 | __tty_fasync(-1, filp, 0); |
1595 | 1647 | ||
@@ -1599,59 +1651,16 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1599 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1651 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1600 | o_tty = tty->link; | 1652 | o_tty = tty->link; |
1601 | 1653 | ||
1602 | #ifdef TTY_PARANOIA_CHECK | 1654 | if (tty_release_checks(tty, o_tty, idx)) { |
1603 | if (idx < 0 || idx >= tty->driver->num) { | ||
1604 | printk(KERN_DEBUG "tty_release_dev: bad idx when trying to " | ||
1605 | "free (%s)\n", tty->name); | ||
1606 | tty_unlock(); | 1655 | tty_unlock(); |
1607 | return 0; | 1656 | return 0; |
1608 | } | 1657 | } |
1609 | if (!devpts) { | ||
1610 | if (tty != tty->driver->ttys[idx]) { | ||
1611 | tty_unlock(); | ||
1612 | printk(KERN_DEBUG "tty_release_dev: driver.table[%d] not tty " | ||
1613 | "for (%s)\n", idx, tty->name); | ||
1614 | return 0; | ||
1615 | } | ||
1616 | if (tty->termios != tty->driver->termios[idx]) { | ||
1617 | tty_unlock(); | ||
1618 | printk(KERN_DEBUG "tty_release_dev: driver.termios[%d] not termios " | ||
1619 | "for (%s)\n", | ||
1620 | idx, tty->name); | ||
1621 | return 0; | ||
1622 | } | ||
1623 | } | ||
1624 | #endif | ||
1625 | 1658 | ||
1626 | #ifdef TTY_DEBUG_HANGUP | 1659 | #ifdef TTY_DEBUG_HANGUP |
1627 | printk(KERN_DEBUG "tty_release_dev of %s (tty count=%d)...", | 1660 | printk(KERN_DEBUG "%s: %s (tty count=%d)...\n", __func__, |
1628 | tty_name(tty, buf), tty->count); | 1661 | tty_name(tty, buf), tty->count); |
1629 | #endif | 1662 | #endif |
1630 | 1663 | ||
1631 | #ifdef TTY_PARANOIA_CHECK | ||
1632 | if (tty->driver->other && | ||
1633 | !(tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | ||
1634 | if (o_tty != tty->driver->other->ttys[idx]) { | ||
1635 | tty_unlock(); | ||
1636 | printk(KERN_DEBUG "tty_release_dev: other->table[%d] " | ||
1637 | "not o_tty for (%s)\n", | ||
1638 | idx, tty->name); | ||
1639 | return 0 ; | ||
1640 | } | ||
1641 | if (o_tty->termios != tty->driver->other->termios[idx]) { | ||
1642 | tty_unlock(); | ||
1643 | printk(KERN_DEBUG "tty_release_dev: other->termios[%d] " | ||
1644 | "not o_termios for (%s)\n", | ||
1645 | idx, tty->name); | ||
1646 | return 0; | ||
1647 | } | ||
1648 | if (o_tty->link != tty) { | ||
1649 | tty_unlock(); | ||
1650 | printk(KERN_DEBUG "tty_release_dev: bad pty pointers\n"); | ||
1651 | return 0; | ||
1652 | } | ||
1653 | } | ||
1654 | #endif | ||
1655 | if (tty->ops->close) | 1664 | if (tty->ops->close) |
1656 | tty->ops->close(tty, filp); | 1665 | tty->ops->close(tty, filp); |
1657 | 1666 | ||
@@ -1707,8 +1716,8 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1707 | if (!do_sleep) | 1716 | if (!do_sleep) |
1708 | break; | 1717 | break; |
1709 | 1718 | ||
1710 | printk(KERN_WARNING "tty_release_dev: %s: read/write wait queue " | 1719 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1711 | "active!\n", tty_name(tty, buf)); | 1720 | __func__, tty_name(tty, buf)); |
1712 | tty_unlock(); | 1721 | tty_unlock(); |
1713 | mutex_unlock(&tty_mutex); | 1722 | mutex_unlock(&tty_mutex); |
1714 | schedule(); | 1723 | schedule(); |
@@ -1721,15 +1730,14 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1721 | */ | 1730 | */ |
1722 | if (pty_master) { | 1731 | if (pty_master) { |
1723 | if (--o_tty->count < 0) { | 1732 | if (--o_tty->count < 0) { |
1724 | printk(KERN_WARNING "tty_release_dev: bad pty slave count " | 1733 | printk(KERN_WARNING "%s: bad pty slave count (%d) for %s\n", |
1725 | "(%d) for %s\n", | 1734 | __func__, o_tty->count, tty_name(o_tty, buf)); |
1726 | o_tty->count, tty_name(o_tty, buf)); | ||
1727 | o_tty->count = 0; | 1735 | o_tty->count = 0; |
1728 | } | 1736 | } |
1729 | } | 1737 | } |
1730 | if (--tty->count < 0) { | 1738 | if (--tty->count < 0) { |
1731 | printk(KERN_WARNING "tty_release_dev: bad tty->count (%d) for %s\n", | 1739 | printk(KERN_WARNING "%s: bad tty->count (%d) for %s\n", |
1732 | tty->count, tty_name(tty, buf)); | 1740 | __func__, tty->count, tty_name(tty, buf)); |
1733 | tty->count = 0; | 1741 | tty->count = 0; |
1734 | } | 1742 | } |
1735 | 1743 | ||
@@ -1778,7 +1786,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1778 | } | 1786 | } |
1779 | 1787 | ||
1780 | #ifdef TTY_DEBUG_HANGUP | 1788 | #ifdef TTY_DEBUG_HANGUP |
1781 | printk(KERN_DEBUG "freeing tty structure..."); | 1789 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); |
1782 | #endif | 1790 | #endif |
1783 | /* | 1791 | /* |
1784 | * Ask the line discipline code to release its structures | 1792 | * Ask the line discipline code to release its structures |
@@ -1798,6 +1806,83 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1798 | } | 1806 | } |
1799 | 1807 | ||
1800 | /** | 1808 | /** |
1809 | * tty_open_current_tty - get tty of current task for open | ||
1810 | * @device: device number | ||
1811 | * @filp: file pointer to tty | ||
1812 | * @return: tty of the current task iff @device is /dev/tty | ||
1813 | * | ||
1814 | * We cannot return driver and index like for the other nodes because | ||
1815 | * devpts will not work then. It expects inodes to be from devpts FS. | ||
1816 | */ | ||
1817 | static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp) | ||
1818 | { | ||
1819 | struct tty_struct *tty; | ||
1820 | |||
1821 | if (device != MKDEV(TTYAUX_MAJOR, 0)) | ||
1822 | return NULL; | ||
1823 | |||
1824 | tty = get_current_tty(); | ||
1825 | if (!tty) | ||
1826 | return ERR_PTR(-ENXIO); | ||
1827 | |||
1828 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | ||
1829 | /* noctty = 1; */ | ||
1830 | tty_kref_put(tty); | ||
1831 | /* FIXME: we put a reference and return a TTY! */ | ||
1832 | return tty; | ||
1833 | } | ||
1834 | |||
1835 | /** | ||
1836 | * tty_lookup_driver - lookup a tty driver for a given device file | ||
1837 | * @device: device number | ||
1838 | * @filp: file pointer to tty | ||
1839 | * @noctty: set if the device should not become a controlling tty | ||
1840 | * @index: index for the device in the @return driver | ||
1841 | * @return: driver for this inode (with increased refcount) | ||
1842 | * | ||
1843 | * If @return is not erroneous, the caller is responsible to decrement the | ||
1844 | * refcount by tty_driver_kref_put. | ||
1845 | * | ||
1846 | * Locking: tty_mutex protects get_tty_driver | ||
1847 | */ | ||
1848 | static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | ||
1849 | int *noctty, int *index) | ||
1850 | { | ||
1851 | struct tty_driver *driver; | ||
1852 | |||
1853 | switch (device) { | ||
1854 | #ifdef CONFIG_VT | ||
1855 | case MKDEV(TTY_MAJOR, 0): { | ||
1856 | extern struct tty_driver *console_driver; | ||
1857 | driver = tty_driver_kref_get(console_driver); | ||
1858 | *index = fg_console; | ||
1859 | *noctty = 1; | ||
1860 | break; | ||
1861 | } | ||
1862 | #endif | ||
1863 | case MKDEV(TTYAUX_MAJOR, 1): { | ||
1864 | struct tty_driver *console_driver = console_device(index); | ||
1865 | if (console_driver) { | ||
1866 | driver = tty_driver_kref_get(console_driver); | ||
1867 | if (driver) { | ||
1868 | /* Don't let /dev/console block */ | ||
1869 | filp->f_flags |= O_NONBLOCK; | ||
1870 | *noctty = 1; | ||
1871 | break; | ||
1872 | } | ||
1873 | } | ||
1874 | return ERR_PTR(-ENODEV); | ||
1875 | } | ||
1876 | default: | ||
1877 | driver = get_tty_driver(device, index); | ||
1878 | if (!driver) | ||
1879 | return ERR_PTR(-ENODEV); | ||
1880 | break; | ||
1881 | } | ||
1882 | return driver; | ||
1883 | } | ||
1884 | |||
1885 | /** | ||
1801 | * tty_open - open a tty device | 1886 | * tty_open - open a tty device |
1802 | * @inode: inode of device file | 1887 | * @inode: inode of device file |
1803 | * @filp: file pointer to tty | 1888 | * @filp: file pointer to tty |
@@ -1813,16 +1898,16 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1813 | * The termios state of a pty is reset on first open so that | 1898 | * The termios state of a pty is reset on first open so that |
1814 | * settings don't persist across reuse. | 1899 | * settings don't persist across reuse. |
1815 | * | 1900 | * |
1816 | * Locking: tty_mutex protects tty, get_tty_driver and tty_init_dev work. | 1901 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
1817 | * tty->count should protect the rest. | 1902 | * tty->count should protect the rest. |
1818 | * ->siglock protects ->signal/->sighand | 1903 | * ->siglock protects ->signal/->sighand |
1819 | */ | 1904 | */ |
1820 | 1905 | ||
1821 | static int tty_open(struct inode *inode, struct file *filp) | 1906 | static int tty_open(struct inode *inode, struct file *filp) |
1822 | { | 1907 | { |
1823 | struct tty_struct *tty = NULL; | 1908 | struct tty_struct *tty; |
1824 | int noctty, retval; | 1909 | int noctty, retval; |
1825 | struct tty_driver *driver; | 1910 | struct tty_driver *driver = NULL; |
1826 | int index; | 1911 | int index; |
1827 | dev_t device = inode->i_rdev; | 1912 | dev_t device = inode->i_rdev; |
1828 | unsigned saved_flags = filp->f_flags; | 1913 | unsigned saved_flags = filp->f_flags; |
@@ -1841,66 +1926,22 @@ retry_open: | |||
1841 | mutex_lock(&tty_mutex); | 1926 | mutex_lock(&tty_mutex); |
1842 | tty_lock(); | 1927 | tty_lock(); |
1843 | 1928 | ||
1844 | if (device == MKDEV(TTYAUX_MAJOR, 0)) { | 1929 | tty = tty_open_current_tty(device, filp); |
1845 | tty = get_current_tty(); | 1930 | if (IS_ERR(tty)) { |
1846 | if (!tty) { | 1931 | retval = PTR_ERR(tty); |
1847 | tty_unlock(); | 1932 | goto err_unlock; |
1848 | mutex_unlock(&tty_mutex); | 1933 | } else if (!tty) { |
1849 | tty_free_file(filp); | 1934 | driver = tty_lookup_driver(device, filp, &noctty, &index); |
1850 | return -ENXIO; | 1935 | if (IS_ERR(driver)) { |
1851 | } | 1936 | retval = PTR_ERR(driver); |
1852 | driver = tty_driver_kref_get(tty->driver); | 1937 | goto err_unlock; |
1853 | index = tty->index; | ||
1854 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | ||
1855 | /* noctty = 1; */ | ||
1856 | /* FIXME: Should we take a driver reference ? */ | ||
1857 | tty_kref_put(tty); | ||
1858 | goto got_driver; | ||
1859 | } | ||
1860 | #ifdef CONFIG_VT | ||
1861 | if (device == MKDEV(TTY_MAJOR, 0)) { | ||
1862 | extern struct tty_driver *console_driver; | ||
1863 | driver = tty_driver_kref_get(console_driver); | ||
1864 | index = fg_console; | ||
1865 | noctty = 1; | ||
1866 | goto got_driver; | ||
1867 | } | ||
1868 | #endif | ||
1869 | if (device == MKDEV(TTYAUX_MAJOR, 1)) { | ||
1870 | struct tty_driver *console_driver = console_device(&index); | ||
1871 | if (console_driver) { | ||
1872 | driver = tty_driver_kref_get(console_driver); | ||
1873 | if (driver) { | ||
1874 | /* Don't let /dev/console block */ | ||
1875 | filp->f_flags |= O_NONBLOCK; | ||
1876 | noctty = 1; | ||
1877 | goto got_driver; | ||
1878 | } | ||
1879 | } | 1938 | } |
1880 | tty_unlock(); | ||
1881 | mutex_unlock(&tty_mutex); | ||
1882 | tty_free_file(filp); | ||
1883 | return -ENODEV; | ||
1884 | } | ||
1885 | 1939 | ||
1886 | driver = get_tty_driver(device, &index); | ||
1887 | if (!driver) { | ||
1888 | tty_unlock(); | ||
1889 | mutex_unlock(&tty_mutex); | ||
1890 | tty_free_file(filp); | ||
1891 | return -ENODEV; | ||
1892 | } | ||
1893 | got_driver: | ||
1894 | if (!tty) { | ||
1895 | /* check whether we're reopening an existing tty */ | 1940 | /* check whether we're reopening an existing tty */ |
1896 | tty = tty_driver_lookup_tty(driver, inode, index); | 1941 | tty = tty_driver_lookup_tty(driver, inode, index); |
1897 | |||
1898 | if (IS_ERR(tty)) { | 1942 | if (IS_ERR(tty)) { |
1899 | tty_unlock(); | 1943 | retval = PTR_ERR(tty); |
1900 | mutex_unlock(&tty_mutex); | 1944 | goto err_unlock; |
1901 | tty_driver_kref_put(driver); | ||
1902 | tty_free_file(filp); | ||
1903 | return PTR_ERR(tty); | ||
1904 | } | 1945 | } |
1905 | } | 1946 | } |
1906 | 1947 | ||
@@ -1912,21 +1953,22 @@ got_driver: | |||
1912 | tty = tty_init_dev(driver, index, 0); | 1953 | tty = tty_init_dev(driver, index, 0); |
1913 | 1954 | ||
1914 | mutex_unlock(&tty_mutex); | 1955 | mutex_unlock(&tty_mutex); |
1915 | tty_driver_kref_put(driver); | 1956 | if (driver) |
1957 | tty_driver_kref_put(driver); | ||
1916 | if (IS_ERR(tty)) { | 1958 | if (IS_ERR(tty)) { |
1917 | tty_unlock(); | 1959 | tty_unlock(); |
1918 | tty_free_file(filp); | 1960 | retval = PTR_ERR(tty); |
1919 | return PTR_ERR(tty); | 1961 | goto err_file; |
1920 | } | 1962 | } |
1921 | 1963 | ||
1922 | tty_add_file(tty, filp); | 1964 | tty_add_file(tty, filp); |
1923 | 1965 | ||
1924 | check_tty_count(tty, "tty_open"); | 1966 | check_tty_count(tty, __func__); |
1925 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1967 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1926 | tty->driver->subtype == PTY_TYPE_MASTER) | 1968 | tty->driver->subtype == PTY_TYPE_MASTER) |
1927 | noctty = 1; | 1969 | noctty = 1; |
1928 | #ifdef TTY_DEBUG_HANGUP | 1970 | #ifdef TTY_DEBUG_HANGUP |
1929 | printk(KERN_DEBUG "opening %s...", tty->name); | 1971 | printk(KERN_DEBUG "%s: opening %s...\n", __func__, tty->name); |
1930 | #endif | 1972 | #endif |
1931 | if (tty->ops->open) | 1973 | if (tty->ops->open) |
1932 | retval = tty->ops->open(tty, filp); | 1974 | retval = tty->ops->open(tty, filp); |
@@ -1940,8 +1982,8 @@ got_driver: | |||
1940 | 1982 | ||
1941 | if (retval) { | 1983 | if (retval) { |
1942 | #ifdef TTY_DEBUG_HANGUP | 1984 | #ifdef TTY_DEBUG_HANGUP |
1943 | printk(KERN_DEBUG "error %d in opening %s...", retval, | 1985 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
1944 | tty->name); | 1986 | retval, tty->name); |
1945 | #endif | 1987 | #endif |
1946 | tty_unlock(); /* need to call tty_release without BTM */ | 1988 | tty_unlock(); /* need to call tty_release without BTM */ |
1947 | tty_release(inode, filp); | 1989 | tty_release(inode, filp); |
@@ -1976,6 +2018,15 @@ got_driver: | |||
1976 | tty_unlock(); | 2018 | tty_unlock(); |
1977 | mutex_unlock(&tty_mutex); | 2019 | mutex_unlock(&tty_mutex); |
1978 | return 0; | 2020 | return 0; |
2021 | err_unlock: | ||
2022 | tty_unlock(); | ||
2023 | mutex_unlock(&tty_mutex); | ||
2024 | /* after locks to avoid deadlock */ | ||
2025 | if (!IS_ERR_OR_NULL(driver)) | ||
2026 | tty_driver_kref_put(driver); | ||
2027 | err_file: | ||
2028 | tty_free_file(filp); | ||
2029 | return retval; | ||
1979 | } | 2030 | } |
1980 | 2031 | ||
1981 | 2032 | ||
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 8e0924f55446..24b95db75d84 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -1,19 +1,11 @@ | |||
1 | #include <linux/types.h> | 1 | #include <linux/types.h> |
2 | #include <linux/major.h> | ||
3 | #include <linux/errno.h> | 2 | #include <linux/errno.h> |
4 | #include <linux/signal.h> | 3 | #include <linux/kmod.h> |
5 | #include <linux/fcntl.h> | ||
6 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
7 | #include <linux/interrupt.h> | 5 | #include <linux/interrupt.h> |
8 | #include <linux/tty.h> | 6 | #include <linux/tty.h> |
9 | #include <linux/tty_driver.h> | 7 | #include <linux/tty_driver.h> |
10 | #include <linux/tty_flip.h> | ||
11 | #include <linux/devpts_fs.h> | ||
12 | #include <linux/file.h> | 8 | #include <linux/file.h> |
13 | #include <linux/console.h> | ||
14 | #include <linux/timer.h> | ||
15 | #include <linux/ctype.h> | ||
16 | #include <linux/kd.h> | ||
17 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
18 | #include <linux/string.h> | 10 | #include <linux/string.h> |
19 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
@@ -24,18 +16,8 @@ | |||
24 | #include <linux/device.h> | 16 | #include <linux/device.h> |
25 | #include <linux/wait.h> | 17 | #include <linux/wait.h> |
26 | #include <linux/bitops.h> | 18 | #include <linux/bitops.h> |
27 | #include <linux/delay.h> | ||
28 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
29 | |||
30 | #include <linux/uaccess.h> | 20 | #include <linux/uaccess.h> |
31 | #include <asm/system.h> | ||
32 | |||
33 | #include <linux/kbd_kern.h> | ||
34 | #include <linux/vt_kern.h> | ||
35 | #include <linux/selection.h> | ||
36 | |||
37 | #include <linux/kmod.h> | ||
38 | #include <linux/nsproxy.h> | ||
39 | #include <linux/ratelimit.h> | 21 | #include <linux/ratelimit.h> |
40 | 22 | ||
41 | /* | 23 | /* |
@@ -558,8 +540,6 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) | |||
558 | long ret; | 540 | long ret; |
559 | ret = wait_event_timeout(tty_ldisc_idle, | 541 | ret = wait_event_timeout(tty_ldisc_idle, |
560 | atomic_read(&tty->ldisc->users) == 1, timeout); | 542 | atomic_read(&tty->ldisc->users) == 1, timeout); |
561 | if (ret < 0) | ||
562 | return ret; | ||
563 | return ret > 0 ? 0 : -EBUSY; | 543 | return ret > 0 ? 0 : -EBUSY; |
564 | } | 544 | } |
565 | 545 | ||
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 45d3e80156d4..a0f3d6c4d39d 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c | |||
@@ -584,7 +584,7 @@ int con_set_default_unimap(struct vc_data *vc) | |||
584 | return 0; | 584 | return 0; |
585 | dflt->refcount++; | 585 | dflt->refcount++; |
586 | *vc->vc_uni_pagedir_loc = (unsigned long)dflt; | 586 | *vc->vc_uni_pagedir_loc = (unsigned long)dflt; |
587 | if (p && --p->refcount) { | 587 | if (p && !--p->refcount) { |
588 | con_release_unimap(p); | 588 | con_release_unimap(p); |
589 | kfree(p); | 589 | kfree(p); |
590 | } | 590 | } |
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 1f05bbeac01e..8f012f8ac8e9 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h | |||
@@ -66,6 +66,7 @@ enum { | |||
66 | * dependent on the 8250 driver. | 66 | * dependent on the 8250 driver. |
67 | */ | 67 | */ |
68 | struct uart_port; | 68 | struct uart_port; |
69 | struct uart_8250_port; | ||
69 | 70 | ||
70 | int serial8250_register_port(struct uart_port *); | 71 | int serial8250_register_port(struct uart_port *); |
71 | void serial8250_unregister_port(int line); | 72 | void serial8250_unregister_port(int line); |
@@ -81,7 +82,11 @@ extern void serial8250_do_set_termios(struct uart_port *port, | |||
81 | struct ktermios *termios, struct ktermios *old); | 82 | struct ktermios *termios, struct ktermios *old); |
82 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, | 83 | extern void serial8250_do_pm(struct uart_port *port, unsigned int state, |
83 | unsigned int oldstate); | 84 | unsigned int oldstate); |
85 | extern int fsl8250_handle_irq(struct uart_port *port); | ||
84 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir); | 86 | int serial8250_handle_irq(struct uart_port *port, unsigned int iir); |
87 | unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr); | ||
88 | void serial8250_tx_chars(struct uart_8250_port *up); | ||
89 | unsigned int serial8250_modem_status(struct uart_8250_port *up); | ||
85 | 90 | ||
86 | extern void serial8250_set_isa_configurator(void (*v) | 91 | extern void serial8250_set_isa_configurator(void (*v) |
87 | (int port, struct uart_port *up, | 92 | (int port, struct uart_port *up, |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index eadf33d0abba..b67305e3ad57 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -351,6 +351,7 @@ struct uart_port { | |||
351 | #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) | 351 | #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) |
352 | #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) | 352 | #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) |
353 | #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) | 353 | #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) |
354 | #define UPF_IIR_ONCE ((__force upf_t) (1 << 26)) | ||
354 | /* The exact UART type is known and should not be probed. */ | 355 | /* The exact UART type is known and should not be probed. */ |
355 | #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) | 356 | #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) |
356 | #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) | 357 | #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) |
@@ -483,10 +484,19 @@ static inline int uart_tx_stopped(struct uart_port *port) | |||
483 | /* | 484 | /* |
484 | * The following are helper functions for the low level drivers. | 485 | * The following are helper functions for the low level drivers. |
485 | */ | 486 | */ |
487 | |||
488 | extern void uart_handle_dcd_change(struct uart_port *uport, | ||
489 | unsigned int status); | ||
490 | extern void uart_handle_cts_change(struct uart_port *uport, | ||
491 | unsigned int status); | ||
492 | |||
493 | extern void uart_insert_char(struct uart_port *port, unsigned int status, | ||
494 | unsigned int overrun, unsigned int ch, unsigned int flag); | ||
495 | |||
496 | #ifdef SUPPORT_SYSRQ | ||
486 | static inline int | 497 | static inline int |
487 | uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) | 498 | uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) |
488 | { | 499 | { |
489 | #ifdef SUPPORT_SYSRQ | ||
490 | if (port->sysrq) { | 500 | if (port->sysrq) { |
491 | if (ch && time_before(jiffies, port->sysrq)) { | 501 | if (ch && time_before(jiffies, port->sysrq)) { |
492 | handle_sysrq(ch); | 502 | handle_sysrq(ch); |
@@ -495,11 +505,10 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) | |||
495 | } | 505 | } |
496 | port->sysrq = 0; | 506 | port->sysrq = 0; |
497 | } | 507 | } |
498 | #endif | ||
499 | return 0; | 508 | return 0; |
500 | } | 509 | } |
501 | #ifndef SUPPORT_SYSRQ | 510 | #else |
502 | #define uart_handle_sysrq_char(port,ch) uart_handle_sysrq_char(port, 0) | 511 | #define uart_handle_sysrq_char(port,ch) ({ (void)port; 0; }) |
503 | #endif | 512 | #endif |
504 | 513 | ||
505 | /* | 514 | /* |
@@ -522,89 +531,6 @@ static inline int uart_handle_break(struct uart_port *port) | |||
522 | return 0; | 531 | return 0; |
523 | } | 532 | } |
524 | 533 | ||
525 | /** | ||
526 | * uart_handle_dcd_change - handle a change of carrier detect state | ||
527 | * @uport: uart_port structure for the open port | ||
528 | * @status: new carrier detect status, nonzero if active | ||
529 | */ | ||
530 | static inline void | ||
531 | uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | ||
532 | { | ||
533 | struct uart_state *state = uport->state; | ||
534 | struct tty_port *port = &state->port; | ||
535 | struct tty_ldisc *ld = tty_ldisc_ref(port->tty); | ||
536 | struct pps_event_time ts; | ||
537 | |||
538 | if (ld && ld->ops->dcd_change) | ||
539 | pps_get_ts(&ts); | ||
540 | |||
541 | uport->icount.dcd++; | ||
542 | #ifdef CONFIG_HARD_PPS | ||
543 | if ((uport->flags & UPF_HARDPPS_CD) && status) | ||
544 | hardpps(); | ||
545 | #endif | ||
546 | |||
547 | if (port->flags & ASYNC_CHECK_CD) { | ||
548 | if (status) | ||
549 | wake_up_interruptible(&port->open_wait); | ||
550 | else if (port->tty) | ||
551 | tty_hangup(port->tty); | ||
552 | } | ||
553 | |||
554 | if (ld && ld->ops->dcd_change) | ||
555 | ld->ops->dcd_change(port->tty, status, &ts); | ||
556 | if (ld) | ||
557 | tty_ldisc_deref(ld); | ||
558 | } | ||
559 | |||
560 | /** | ||
561 | * uart_handle_cts_change - handle a change of clear-to-send state | ||
562 | * @uport: uart_port structure for the open port | ||
563 | * @status: new clear to send status, nonzero if active | ||
564 | */ | ||
565 | static inline void | ||
566 | uart_handle_cts_change(struct uart_port *uport, unsigned int status) | ||
567 | { | ||
568 | struct tty_port *port = &uport->state->port; | ||
569 | struct tty_struct *tty = port->tty; | ||
570 | |||
571 | uport->icount.cts++; | ||
572 | |||
573 | if (port->flags & ASYNC_CTS_FLOW) { | ||
574 | if (tty->hw_stopped) { | ||
575 | if (status) { | ||
576 | tty->hw_stopped = 0; | ||
577 | uport->ops->start_tx(uport); | ||
578 | uart_write_wakeup(uport); | ||
579 | } | ||
580 | } else { | ||
581 | if (!status) { | ||
582 | tty->hw_stopped = 1; | ||
583 | uport->ops->stop_tx(uport); | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | } | ||
588 | |||
589 | #include <linux/tty_flip.h> | ||
590 | |||
591 | static inline void | ||
592 | uart_insert_char(struct uart_port *port, unsigned int status, | ||
593 | unsigned int overrun, unsigned int ch, unsigned int flag) | ||
594 | { | ||
595 | struct tty_struct *tty = port->state->port.tty; | ||
596 | |||
597 | if ((status & port->ignore_status_mask & ~overrun) == 0) | ||
598 | tty_insert_flip_char(tty, ch, flag); | ||
599 | |||
600 | /* | ||
601 | * Overrun is special. Since it's reported immediately, | ||
602 | * it doesn't affect the current character. | ||
603 | */ | ||
604 | if (status & ~port->ignore_status_mask & overrun) | ||
605 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
606 | } | ||
607 | |||
608 | /* | 534 | /* |
609 | * UART_ENABLE_MS - determine if port should enable modem status irqs | 535 | * UART_ENABLE_MS - determine if port should enable modem status irqs |
610 | */ | 536 | */ |