diff options
Diffstat (limited to 'drivers')
50 files changed, 2186 insertions, 524 deletions
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 3c5f2491a16f..bc912611fe09 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1043,11 +1043,6 @@ isdn_tty_change_speed(modem_info *info) | |||
1043 | if (!(cflag & PARODD)) | 1043 | if (!(cflag & PARODD)) |
1044 | cval |= UART_LCR_EPAR; | 1044 | cval |= UART_LCR_EPAR; |
1045 | 1045 | ||
1046 | /* CTS flow control flag and modem status interrupts */ | ||
1047 | if (cflag & CRTSCTS) { | ||
1048 | port->flags |= ASYNC_CTS_FLOW; | ||
1049 | } else | ||
1050 | port->flags &= ~ASYNC_CTS_FLOW; | ||
1051 | if (cflag & CLOCAL) | 1046 | if (cflag & CLOCAL) |
1052 | port->flags &= ~ASYNC_CHECK_CD; | 1047 | port->flags &= ~ASYNC_CHECK_CD; |
1053 | else { | 1048 | else { |
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 29cc2e4ba935..21546659ff07 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c | |||
@@ -112,19 +112,6 @@ static struct pci_device_id dgnc_pci_tbl[] = { | |||
112 | { DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, | 112 | { DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, |
113 | { DIGI_VID, PCI_DEVICE_CLASSIC_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, | 113 | { DIGI_VID, PCI_DEVICE_CLASSIC_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, |
114 | { DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, | 114 | { DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, |
115 | { DIGI_VID, PCI_DEVICE_NEO_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, | ||
116 | { DIGI_VID, PCI_DEVICE_NEO_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, | ||
117 | { DIGI_VID, PCI_DEVICE_NEO_2DB9_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 }, | ||
118 | { DIGI_VID, PCI_DEVICE_NEO_2DB9PRI_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, | ||
119 | { DIGI_VID, PCI_DEVICE_NEO_2RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, | ||
120 | { DIGI_VID, PCI_DEVICE_NEO_2RJ45PRI_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, | ||
121 | { DIGI_VID, PCI_DEVICE_NEO_1_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, | ||
122 | { DIGI_VID, PCI_DEVICE_NEO_1_422_485_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, | ||
123 | { DIGI_VID, PCI_DEVICE_NEO_2_422_485_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, | ||
124 | { DIGI_VID, PCI_DEVICE_NEO_EXPRESS_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, | ||
125 | { DIGI_VID, PCI_DEVICE_NEO_EXPRESS_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, | ||
126 | { DIGI_VID, PCI_DEVICE_NEO_EXPRESS_4RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, | ||
127 | { DIGI_VID, PCI_DEVICE_NEO_EXPRESS_8RJ45_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, | ||
128 | {0,} /* 0 terminated list. */ | 115 | {0,} /* 0 terminated list. */ |
129 | }; | 116 | }; |
130 | MODULE_DEVICE_TABLE(pci, dgnc_pci_tbl); | 117 | MODULE_DEVICE_TABLE(pci, dgnc_pci_tbl); |
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 2dc2831840ca..2967f0388d2c 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
@@ -402,9 +402,6 @@ static int xencons_connect_backend(struct xenbus_device *dev, | |||
402 | evtchn); | 402 | evtchn); |
403 | if (ret) | 403 | if (ret) |
404 | goto error_xenbus; | 404 | goto error_xenbus; |
405 | ret = xenbus_printf(xbt, dev->nodename, "type", "ioemu"); | ||
406 | if (ret) | ||
407 | goto error_xenbus; | ||
408 | ret = xenbus_transaction_end(xbt, 0); | 405 | ret = xenbus_transaction_end(xbt, 0); |
409 | if (ret) { | 406 | if (ret) { |
410 | if (ret == -EAGAIN) | 407 | if (ret == -EAGAIN) |
diff --git a/drivers/tty/metag_da.c b/drivers/tty/metag_da.c index 7332e2ca4615..3774600741d8 100644 --- a/drivers/tty/metag_da.c +++ b/drivers/tty/metag_da.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/kthread.h> | 19 | #include <linux/kthread.h> |
20 | #include <linux/moduleparam.h> | ||
20 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
21 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
22 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
@@ -70,6 +71,15 @@ static struct tty_driver *channel_driver; | |||
70 | static struct timer_list put_timer; | 71 | static struct timer_list put_timer; |
71 | static struct task_struct *dashtty_thread; | 72 | static struct task_struct *dashtty_thread; |
72 | 73 | ||
74 | /* | ||
75 | * The console_poll parameter determines whether the console channel should be | ||
76 | * polled for input. | ||
77 | * By default the console channel isn't polled at all, in order to avoid the | ||
78 | * overhead, but that means it isn't possible to have a login on /dev/console. | ||
79 | */ | ||
80 | static bool console_poll; | ||
81 | module_param(console_poll, bool, S_IRUGO); | ||
82 | |||
73 | #define RX_BUF_SIZE 1024 | 83 | #define RX_BUF_SIZE 1024 |
74 | 84 | ||
75 | enum { | 85 | enum { |
@@ -353,7 +363,7 @@ static int dashtty_port_activate(struct tty_port *port, struct tty_struct *tty) | |||
353 | * possible to have a login on /dev/console. | 363 | * possible to have a login on /dev/console. |
354 | * | 364 | * |
355 | */ | 365 | */ |
356 | if (dport != &dashtty_ports[CONSOLE_CHANNEL]) | 366 | if (console_poll || dport != &dashtty_ports[CONSOLE_CHANNEL]) |
357 | if (atomic_inc_return(&num_channels_need_poll) == 1) | 367 | if (atomic_inc_return(&num_channels_need_poll) == 1) |
358 | add_poll_timer(&poll_timer); | 368 | add_poll_timer(&poll_timer); |
359 | 369 | ||
@@ -372,7 +382,7 @@ static void dashtty_port_shutdown(struct tty_port *port) | |||
372 | unsigned int count; | 382 | unsigned int count; |
373 | 383 | ||
374 | /* stop reading */ | 384 | /* stop reading */ |
375 | if (dport != &dashtty_ports[CONSOLE_CHANNEL]) | 385 | if (console_poll || dport != &dashtty_ports[CONSOLE_CHANNEL]) |
376 | if (atomic_dec_and_test(&num_channels_need_poll)) | 386 | if (atomic_dec_and_test(&num_channels_need_poll)) |
377 | del_timer_sync(&poll_timer); | 387 | del_timer_sync(&poll_timer); |
378 | 388 | ||
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 1deaca4674e4..14c54e041065 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
@@ -1096,7 +1096,7 @@ static int __init moxa_init(void) | |||
1096 | continue; | 1096 | continue; |
1097 | } | 1097 | } |
1098 | 1098 | ||
1099 | printk(KERN_INFO "MOXA isa board found at 0x%.8lu and " | 1099 | printk(KERN_INFO "MOXA isa board found at 0x%.8lx and " |
1100 | "ready (%u ports, firmware loaded)\n", | 1100 | "ready (%u ports, firmware loaded)\n", |
1101 | baseaddr[i], brd->numPorts); | 1101 | baseaddr[i], brd->numPorts); |
1102 | 1102 | ||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index f44f1ba762c3..89c4cee253e3 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -1166,7 +1166,7 @@ static void n_tty_receive_break(struct tty_struct *tty) | |||
1166 | } | 1166 | } |
1167 | put_tty_queue('\0', ldata); | 1167 | put_tty_queue('\0', ldata); |
1168 | if (waitqueue_active(&tty->read_wait)) | 1168 | if (waitqueue_active(&tty->read_wait)) |
1169 | wake_up_interruptible(&tty->read_wait); | 1169 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | /** | 1172 | /** |
@@ -1226,7 +1226,7 @@ static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c) | |||
1226 | } else | 1226 | } else |
1227 | put_tty_queue(c, ldata); | 1227 | put_tty_queue(c, ldata); |
1228 | if (waitqueue_active(&tty->read_wait)) | 1228 | if (waitqueue_active(&tty->read_wait)) |
1229 | wake_up_interruptible(&tty->read_wait); | 1229 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
1230 | } | 1230 | } |
1231 | 1231 | ||
1232 | static void | 1232 | static void |
@@ -1378,7 +1378,7 @@ handle_newline: | |||
1378 | ldata->canon_head = ldata->read_head; | 1378 | ldata->canon_head = ldata->read_head; |
1379 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1379 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1380 | if (waitqueue_active(&tty->read_wait)) | 1380 | if (waitqueue_active(&tty->read_wait)) |
1381 | wake_up_interruptible(&tty->read_wait); | 1381 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
1382 | return 0; | 1382 | return 0; |
1383 | } | 1383 | } |
1384 | } | 1384 | } |
@@ -1679,7 +1679,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1679 | L_EXTPROC(tty)) { | 1679 | L_EXTPROC(tty)) { |
1680 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1680 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1681 | if (waitqueue_active(&tty->read_wait)) | 1681 | if (waitqueue_active(&tty->read_wait)) |
1682 | wake_up_interruptible(&tty->read_wait); | 1682 | wake_up_interruptible_poll(&tty->read_wait, POLLIN); |
1683 | } | 1683 | } |
1684 | } | 1684 | } |
1685 | 1685 | ||
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index cd0429369557..74885af8c7bd 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -523,7 +523,7 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf, | |||
523 | } | 523 | } |
524 | 524 | ||
525 | /* Setup pointers to different channels and also setup buffer sizes. */ | 525 | /* Setup pointers to different channels and also setup buffer sizes. */ |
526 | static void setup_memory(struct nozomi *dc) | 526 | static void nozomi_setup_memory(struct nozomi *dc) |
527 | { | 527 | { |
528 | void __iomem *offset = dc->base_addr + dc->config_table.dl_start; | 528 | void __iomem *offset = dc->base_addr + dc->config_table.dl_start; |
529 | /* The length reported is including the length field of 4 bytes, | 529 | /* The length reported is including the length field of 4 bytes, |
@@ -671,7 +671,7 @@ static int nozomi_read_config_table(struct nozomi *dc) | |||
671 | int i; | 671 | int i; |
672 | DBG1("Second phase, configuring card"); | 672 | DBG1("Second phase, configuring card"); |
673 | 673 | ||
674 | setup_memory(dc); | 674 | nozomi_setup_memory(dc); |
675 | 675 | ||
676 | dc->port[PORT_MDM].toggle_ul = dc->config_table.toggle.mdm_ul; | 676 | dc->port[PORT_MDM].toggle_ul = dc->config_table.toggle.mdm_ul; |
677 | dc->port[PORT_MDM].toggle_dl = dc->config_table.toggle.mdm_dl; | 677 | dc->port[PORT_MDM].toggle_dl = dc->config_table.toggle.mdm_dl; |
@@ -705,7 +705,7 @@ static int nozomi_read_config_table(struct nozomi *dc) | |||
705 | dc->config_table.version); | 705 | dc->config_table.version); |
706 | 706 | ||
707 | /* Here we should disable all I/O over F32. */ | 707 | /* Here we should disable all I/O over F32. */ |
708 | setup_memory(dc); | 708 | nozomi_setup_memory(dc); |
709 | 709 | ||
710 | /* | 710 | /* |
711 | * We should send ALL channel pair tokens back along | 711 | * We should send ALL channel pair tokens back along |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 9bbdb1de12e2..7c4447a5c0f4 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/devpts_fs.h> | 24 | #include <linux/devpts_fs.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/poll.h> | ||
27 | 28 | ||
28 | 29 | ||
29 | #ifdef CONFIG_UNIX98_PTYS | 30 | #ifdef CONFIG_UNIX98_PTYS |
@@ -313,6 +314,42 @@ done: | |||
313 | } | 314 | } |
314 | 315 | ||
315 | /** | 316 | /** |
317 | * pty_start - start() handler | ||
318 | * pty_stop - stop() handler | ||
319 | * @tty: tty being flow-controlled | ||
320 | * | ||
321 | * Propagates the TIOCPKT status to the master pty. | ||
322 | * | ||
323 | * NB: only the master pty can be in packet mode so only the slave | ||
324 | * needs start()/stop() handlers | ||
325 | */ | ||
326 | static void pty_start(struct tty_struct *tty) | ||
327 | { | ||
328 | unsigned long flags; | ||
329 | |||
330 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
331 | if (tty->link && tty->link->packet) { | ||
332 | tty->ctrl_status &= ~TIOCPKT_STOP; | ||
333 | tty->ctrl_status |= TIOCPKT_START; | ||
334 | wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); | ||
335 | } | ||
336 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
337 | } | ||
338 | |||
339 | static void pty_stop(struct tty_struct *tty) | ||
340 | { | ||
341 | unsigned long flags; | ||
342 | |||
343 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
344 | if (tty->link && tty->link->packet) { | ||
345 | tty->ctrl_status &= ~TIOCPKT_START; | ||
346 | tty->ctrl_status |= TIOCPKT_STOP; | ||
347 | wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); | ||
348 | } | ||
349 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
350 | } | ||
351 | |||
352 | /** | ||
316 | * pty_common_install - set up the pty pair | 353 | * pty_common_install - set up the pty pair |
317 | * @driver: the pty driver | 354 | * @driver: the pty driver |
318 | * @tty: the tty being instantiated | 355 | * @tty: the tty being instantiated |
@@ -471,6 +508,8 @@ static const struct tty_operations slave_pty_ops_bsd = { | |||
471 | .set_termios = pty_set_termios, | 508 | .set_termios = pty_set_termios, |
472 | .cleanup = pty_cleanup, | 509 | .cleanup = pty_cleanup, |
473 | .resize = pty_resize, | 510 | .resize = pty_resize, |
511 | .start = pty_start, | ||
512 | .stop = pty_stop, | ||
474 | .remove = pty_remove | 513 | .remove = pty_remove |
475 | }; | 514 | }; |
476 | 515 | ||
@@ -646,6 +685,8 @@ static const struct tty_operations pty_unix98_ops = { | |||
646 | .chars_in_buffer = pty_chars_in_buffer, | 685 | .chars_in_buffer = pty_chars_in_buffer, |
647 | .unthrottle = pty_unthrottle, | 686 | .unthrottle = pty_unthrottle, |
648 | .set_termios = pty_set_termios, | 687 | .set_termios = pty_set_termios, |
688 | .start = pty_start, | ||
689 | .stop = pty_stop, | ||
649 | .shutdown = pty_unix98_shutdown, | 690 | .shutdown = pty_unix98_shutdown, |
650 | .cleanup = pty_cleanup, | 691 | .cleanup = pty_cleanup, |
651 | }; | 692 | }; |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 1b08c918cd51..1bcb4b2141a6 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -72,6 +72,7 @@ struct serial8250_config { | |||
72 | #define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */ | 72 | #define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */ |
73 | #define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */ | 73 | #define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */ |
74 | #define UART_CAP_HFIFO (1 << 14) /* UART has a "hidden" FIFO */ | 74 | #define UART_CAP_HFIFO (1 << 14) /* UART has a "hidden" FIFO */ |
75 | #define UART_CAP_RPM (1 << 15) /* Runtime PM is active while idle */ | ||
75 | 76 | ||
76 | #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ | 77 | #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ |
77 | #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ | 78 | #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ |
@@ -112,6 +113,8 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value) | |||
112 | up->dl_write(up, value); | 113 | up->dl_write(up, value); |
113 | } | 114 | } |
114 | 115 | ||
116 | struct uart_8250_port *serial8250_get_port(int line); | ||
117 | |||
115 | #if defined(__alpha__) && !defined(CONFIG_PCI) | 118 | #if defined(__alpha__) && !defined(CONFIG_PCI) |
116 | /* | 119 | /* |
117 | * Digital did something really horribly wrong with the OUT1 and OUT2 | 120 | * Digital did something really horribly wrong with the OUT1 and OUT2 |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index bd672948f2f1..ca5cfdc1459a 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <linux/nmi.h> | 37 | #include <linux/nmi.h> |
38 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/uaccess.h> | ||
41 | #include <linux/pm_runtime.h> | ||
40 | #ifdef CONFIG_SPARC | 42 | #ifdef CONFIG_SPARC |
41 | #include <linux/sunserialcore.h> | 43 | #include <linux/sunserialcore.h> |
42 | #endif | 44 | #endif |
@@ -539,6 +541,53 @@ void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) | |||
539 | } | 541 | } |
540 | EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); | 542 | EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos); |
541 | 543 | ||
544 | static void serial8250_rpm_get(struct uart_8250_port *p) | ||
545 | { | ||
546 | if (!(p->capabilities & UART_CAP_RPM)) | ||
547 | return; | ||
548 | pm_runtime_get_sync(p->port.dev); | ||
549 | } | ||
550 | |||
551 | static void serial8250_rpm_put(struct uart_8250_port *p) | ||
552 | { | ||
553 | if (!(p->capabilities & UART_CAP_RPM)) | ||
554 | return; | ||
555 | pm_runtime_mark_last_busy(p->port.dev); | ||
556 | pm_runtime_put_autosuspend(p->port.dev); | ||
557 | } | ||
558 | |||
559 | /* | ||
560 | * This two wrapper ensure, that enable_runtime_pm_tx() can be called more than | ||
561 | * once and disable_runtime_pm_tx() will still disable RPM because the fifo is | ||
562 | * empty and the HW can idle again. | ||
563 | */ | ||
564 | static void serial8250_rpm_get_tx(struct uart_8250_port *p) | ||
565 | { | ||
566 | unsigned char rpm_active; | ||
567 | |||
568 | if (!(p->capabilities & UART_CAP_RPM)) | ||
569 | return; | ||
570 | |||
571 | rpm_active = xchg(&p->rpm_tx_active, 1); | ||
572 | if (rpm_active) | ||
573 | return; | ||
574 | pm_runtime_get_sync(p->port.dev); | ||
575 | } | ||
576 | |||
577 | static void serial8250_rpm_put_tx(struct uart_8250_port *p) | ||
578 | { | ||
579 | unsigned char rpm_active; | ||
580 | |||
581 | if (!(p->capabilities & UART_CAP_RPM)) | ||
582 | return; | ||
583 | |||
584 | rpm_active = xchg(&p->rpm_tx_active, 0); | ||
585 | if (!rpm_active) | ||
586 | return; | ||
587 | pm_runtime_mark_last_busy(p->port.dev); | ||
588 | pm_runtime_put_autosuspend(p->port.dev); | ||
589 | } | ||
590 | |||
542 | /* | 591 | /* |
543 | * IER sleep support. UARTs which have EFRs need the "extended | 592 | * IER sleep support. UARTs which have EFRs need the "extended |
544 | * capability" bit enabled. Note that on XR16C850s, we need to | 593 | * capability" bit enabled. Note that on XR16C850s, we need to |
@@ -553,10 +602,11 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | |||
553 | * offset but the UART channel may only write to the corresponding | 602 | * offset but the UART channel may only write to the corresponding |
554 | * bit. | 603 | * bit. |
555 | */ | 604 | */ |
605 | serial8250_rpm_get(p); | ||
556 | if ((p->port.type == PORT_XR17V35X) || | 606 | if ((p->port.type == PORT_XR17V35X) || |
557 | (p->port.type == PORT_XR17D15X)) { | 607 | (p->port.type == PORT_XR17D15X)) { |
558 | serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0); | 608 | serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0); |
559 | return; | 609 | goto out; |
560 | } | 610 | } |
561 | 611 | ||
562 | if (p->capabilities & UART_CAP_SLEEP) { | 612 | if (p->capabilities & UART_CAP_SLEEP) { |
@@ -572,6 +622,8 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | |||
572 | serial_out(p, UART_LCR, 0); | 622 | serial_out(p, UART_LCR, 0); |
573 | } | 623 | } |
574 | } | 624 | } |
625 | out: | ||
626 | serial8250_rpm_put(p); | ||
575 | } | 627 | } |
576 | 628 | ||
577 | #ifdef CONFIG_SERIAL_8250_RSA | 629 | #ifdef CONFIG_SERIAL_8250_RSA |
@@ -1272,6 +1324,7 @@ static inline void __stop_tx(struct uart_8250_port *p) | |||
1272 | if (p->ier & UART_IER_THRI) { | 1324 | if (p->ier & UART_IER_THRI) { |
1273 | p->ier &= ~UART_IER_THRI; | 1325 | p->ier &= ~UART_IER_THRI; |
1274 | serial_out(p, UART_IER, p->ier); | 1326 | serial_out(p, UART_IER, p->ier); |
1327 | serial8250_rpm_put_tx(p); | ||
1275 | } | 1328 | } |
1276 | } | 1329 | } |
1277 | 1330 | ||
@@ -1279,6 +1332,7 @@ static void serial8250_stop_tx(struct uart_port *port) | |||
1279 | { | 1332 | { |
1280 | struct uart_8250_port *up = up_to_u8250p(port); | 1333 | struct uart_8250_port *up = up_to_u8250p(port); |
1281 | 1334 | ||
1335 | serial8250_rpm_get(up); | ||
1282 | __stop_tx(up); | 1336 | __stop_tx(up); |
1283 | 1337 | ||
1284 | /* | 1338 | /* |
@@ -1288,12 +1342,14 @@ static void serial8250_stop_tx(struct uart_port *port) | |||
1288 | up->acr |= UART_ACR_TXDIS; | 1342 | up->acr |= UART_ACR_TXDIS; |
1289 | serial_icr_write(up, UART_ACR, up->acr); | 1343 | serial_icr_write(up, UART_ACR, up->acr); |
1290 | } | 1344 | } |
1345 | serial8250_rpm_put(up); | ||
1291 | } | 1346 | } |
1292 | 1347 | ||
1293 | static void serial8250_start_tx(struct uart_port *port) | 1348 | static void serial8250_start_tx(struct uart_port *port) |
1294 | { | 1349 | { |
1295 | struct uart_8250_port *up = up_to_u8250p(port); | 1350 | struct uart_8250_port *up = up_to_u8250p(port); |
1296 | 1351 | ||
1352 | serial8250_rpm_get_tx(up); | ||
1297 | if (up->dma && !serial8250_tx_dma(up)) { | 1353 | if (up->dma && !serial8250_tx_dma(up)) { |
1298 | return; | 1354 | return; |
1299 | } else if (!(up->ier & UART_IER_THRI)) { | 1355 | } else if (!(up->ier & UART_IER_THRI)) { |
@@ -1318,13 +1374,27 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1318 | } | 1374 | } |
1319 | } | 1375 | } |
1320 | 1376 | ||
1377 | static void serial8250_throttle(struct uart_port *port) | ||
1378 | { | ||
1379 | port->throttle(port); | ||
1380 | } | ||
1381 | |||
1382 | static void serial8250_unthrottle(struct uart_port *port) | ||
1383 | { | ||
1384 | port->unthrottle(port); | ||
1385 | } | ||
1386 | |||
1321 | static void serial8250_stop_rx(struct uart_port *port) | 1387 | static void serial8250_stop_rx(struct uart_port *port) |
1322 | { | 1388 | { |
1323 | struct uart_8250_port *up = up_to_u8250p(port); | 1389 | struct uart_8250_port *up = up_to_u8250p(port); |
1324 | 1390 | ||
1325 | up->ier &= ~UART_IER_RLSI; | 1391 | serial8250_rpm_get(up); |
1392 | |||
1393 | up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); | ||
1326 | up->port.read_status_mask &= ~UART_LSR_DR; | 1394 | up->port.read_status_mask &= ~UART_LSR_DR; |
1327 | serial_port_out(port, UART_IER, up->ier); | 1395 | serial_port_out(port, UART_IER, up->ier); |
1396 | |||
1397 | serial8250_rpm_put(up); | ||
1328 | } | 1398 | } |
1329 | 1399 | ||
1330 | static void serial8250_enable_ms(struct uart_port *port) | 1400 | static void serial8250_enable_ms(struct uart_port *port) |
@@ -1336,7 +1406,10 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
1336 | return; | 1406 | return; |
1337 | 1407 | ||
1338 | up->ier |= UART_IER_MSI; | 1408 | up->ier |= UART_IER_MSI; |
1409 | |||
1410 | serial8250_rpm_get(up); | ||
1339 | serial_port_out(port, UART_IER, up->ier); | 1411 | serial_port_out(port, UART_IER, up->ier); |
1412 | serial8250_rpm_put(up); | ||
1340 | } | 1413 | } |
1341 | 1414 | ||
1342 | /* | 1415 | /* |
@@ -1458,11 +1531,17 @@ void serial8250_tx_chars(struct uart_8250_port *up) | |||
1458 | 1531 | ||
1459 | DEBUG_INTR("THRE..."); | 1532 | DEBUG_INTR("THRE..."); |
1460 | 1533 | ||
1461 | if (uart_circ_empty(xmit)) | 1534 | /* |
1535 | * With RPM enabled, we have to wait once the FIFO is empty before the | ||
1536 | * HW can go idle. So we get here once again with empty FIFO and disable | ||
1537 | * the interrupt and RPM in __stop_tx() | ||
1538 | */ | ||
1539 | if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM)) | ||
1462 | __stop_tx(up); | 1540 | __stop_tx(up); |
1463 | } | 1541 | } |
1464 | EXPORT_SYMBOL_GPL(serial8250_tx_chars); | 1542 | EXPORT_SYMBOL_GPL(serial8250_tx_chars); |
1465 | 1543 | ||
1544 | /* Caller holds uart port lock */ | ||
1466 | unsigned int serial8250_modem_status(struct uart_8250_port *up) | 1545 | unsigned int serial8250_modem_status(struct uart_8250_port *up) |
1467 | { | 1546 | { |
1468 | struct uart_port *port = &up->port; | 1547 | struct uart_port *port = &up->port; |
@@ -1525,9 +1604,17 @@ EXPORT_SYMBOL_GPL(serial8250_handle_irq); | |||
1525 | 1604 | ||
1526 | static int serial8250_default_handle_irq(struct uart_port *port) | 1605 | static int serial8250_default_handle_irq(struct uart_port *port) |
1527 | { | 1606 | { |
1528 | unsigned int iir = serial_port_in(port, UART_IIR); | 1607 | struct uart_8250_port *up = up_to_u8250p(port); |
1608 | unsigned int iir; | ||
1609 | int ret; | ||
1610 | |||
1611 | serial8250_rpm_get(up); | ||
1529 | 1612 | ||
1530 | return serial8250_handle_irq(port, iir); | 1613 | iir = serial_port_in(port, UART_IIR); |
1614 | ret = serial8250_handle_irq(port, iir); | ||
1615 | |||
1616 | serial8250_rpm_put(up); | ||
1617 | return ret; | ||
1531 | } | 1618 | } |
1532 | 1619 | ||
1533 | /* | 1620 | /* |
@@ -1784,11 +1871,15 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
1784 | unsigned long flags; | 1871 | unsigned long flags; |
1785 | unsigned int lsr; | 1872 | unsigned int lsr; |
1786 | 1873 | ||
1874 | serial8250_rpm_get(up); | ||
1875 | |||
1787 | spin_lock_irqsave(&port->lock, flags); | 1876 | spin_lock_irqsave(&port->lock, flags); |
1788 | lsr = serial_port_in(port, UART_LSR); | 1877 | lsr = serial_port_in(port, UART_LSR); |
1789 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1878 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1790 | spin_unlock_irqrestore(&port->lock, flags); | 1879 | spin_unlock_irqrestore(&port->lock, flags); |
1791 | 1880 | ||
1881 | serial8250_rpm_put(up); | ||
1882 | |||
1792 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; | 1883 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; |
1793 | } | 1884 | } |
1794 | 1885 | ||
@@ -1798,7 +1889,9 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port) | |||
1798 | unsigned int status; | 1889 | unsigned int status; |
1799 | unsigned int ret; | 1890 | unsigned int ret; |
1800 | 1891 | ||
1892 | serial8250_rpm_get(up); | ||
1801 | status = serial8250_modem_status(up); | 1893 | status = serial8250_modem_status(up); |
1894 | serial8250_rpm_put(up); | ||
1802 | 1895 | ||
1803 | ret = 0; | 1896 | ret = 0; |
1804 | if (status & UART_MSR_DCD) | 1897 | if (status & UART_MSR_DCD) |
@@ -1838,6 +1931,7 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) | |||
1838 | struct uart_8250_port *up = up_to_u8250p(port); | 1931 | struct uart_8250_port *up = up_to_u8250p(port); |
1839 | unsigned long flags; | 1932 | unsigned long flags; |
1840 | 1933 | ||
1934 | serial8250_rpm_get(up); | ||
1841 | spin_lock_irqsave(&port->lock, flags); | 1935 | spin_lock_irqsave(&port->lock, flags); |
1842 | if (break_state == -1) | 1936 | if (break_state == -1) |
1843 | up->lcr |= UART_LCR_SBC; | 1937 | up->lcr |= UART_LCR_SBC; |
@@ -1845,6 +1939,7 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) | |||
1845 | up->lcr &= ~UART_LCR_SBC; | 1939 | up->lcr &= ~UART_LCR_SBC; |
1846 | serial_port_out(port, UART_LCR, up->lcr); | 1940 | serial_port_out(port, UART_LCR, up->lcr); |
1847 | spin_unlock_irqrestore(&port->lock, flags); | 1941 | spin_unlock_irqrestore(&port->lock, flags); |
1942 | serial8250_rpm_put(up); | ||
1848 | } | 1943 | } |
1849 | 1944 | ||
1850 | /* | 1945 | /* |
@@ -1889,12 +1984,23 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
1889 | 1984 | ||
1890 | static int serial8250_get_poll_char(struct uart_port *port) | 1985 | static int serial8250_get_poll_char(struct uart_port *port) |
1891 | { | 1986 | { |
1892 | unsigned char lsr = serial_port_in(port, UART_LSR); | 1987 | struct uart_8250_port *up = up_to_u8250p(port); |
1988 | unsigned char lsr; | ||
1989 | int status; | ||
1990 | |||
1991 | serial8250_rpm_get(up); | ||
1992 | |||
1993 | lsr = serial_port_in(port, UART_LSR); | ||
1893 | 1994 | ||
1894 | if (!(lsr & UART_LSR_DR)) | 1995 | if (!(lsr & UART_LSR_DR)) { |
1895 | return NO_POLL_CHAR; | 1996 | status = NO_POLL_CHAR; |
1997 | goto out; | ||
1998 | } | ||
1896 | 1999 | ||
1897 | return serial_port_in(port, UART_RX); | 2000 | status = serial_port_in(port, UART_RX); |
2001 | out: | ||
2002 | serial8250_rpm_put(up); | ||
2003 | return status; | ||
1898 | } | 2004 | } |
1899 | 2005 | ||
1900 | 2006 | ||
@@ -1904,6 +2010,7 @@ static void serial8250_put_poll_char(struct uart_port *port, | |||
1904 | unsigned int ier; | 2010 | unsigned int ier; |
1905 | struct uart_8250_port *up = up_to_u8250p(port); | 2011 | struct uart_8250_port *up = up_to_u8250p(port); |
1906 | 2012 | ||
2013 | serial8250_rpm_get(up); | ||
1907 | /* | 2014 | /* |
1908 | * First save the IER then disable the interrupts | 2015 | * First save the IER then disable the interrupts |
1909 | */ | 2016 | */ |
@@ -1925,11 +2032,12 @@ static void serial8250_put_poll_char(struct uart_port *port, | |||
1925 | */ | 2032 | */ |
1926 | wait_for_xmitr(up, BOTH_EMPTY); | 2033 | wait_for_xmitr(up, BOTH_EMPTY); |
1927 | serial_port_out(port, UART_IER, ier); | 2034 | serial_port_out(port, UART_IER, ier); |
2035 | serial8250_rpm_put(up); | ||
1928 | } | 2036 | } |
1929 | 2037 | ||
1930 | #endif /* CONFIG_CONSOLE_POLL */ | 2038 | #endif /* CONFIG_CONSOLE_POLL */ |
1931 | 2039 | ||
1932 | static int serial8250_startup(struct uart_port *port) | 2040 | int serial8250_do_startup(struct uart_port *port) |
1933 | { | 2041 | { |
1934 | struct uart_8250_port *up = up_to_u8250p(port); | 2042 | struct uart_8250_port *up = up_to_u8250p(port); |
1935 | unsigned long flags; | 2043 | unsigned long flags; |
@@ -1950,6 +2058,7 @@ static int serial8250_startup(struct uart_port *port) | |||
1950 | if (port->iotype != up->cur_iotype) | 2058 | if (port->iotype != up->cur_iotype) |
1951 | set_io_from_upio(port); | 2059 | set_io_from_upio(port); |
1952 | 2060 | ||
2061 | serial8250_rpm_get(up); | ||
1953 | if (port->type == PORT_16C950) { | 2062 | if (port->type == PORT_16C950) { |
1954 | /* Wake up and initialize UART */ | 2063 | /* Wake up and initialize UART */ |
1955 | up->acr = 0; | 2064 | up->acr = 0; |
@@ -1970,7 +2079,6 @@ static int serial8250_startup(struct uart_port *port) | |||
1970 | */ | 2079 | */ |
1971 | enable_rsa(up); | 2080 | enable_rsa(up); |
1972 | #endif | 2081 | #endif |
1973 | |||
1974 | /* | 2082 | /* |
1975 | * Clear the FIFO buffers and disable them. | 2083 | * Clear the FIFO buffers and disable them. |
1976 | * (they will be reenabled in set_termios()) | 2084 | * (they will be reenabled in set_termios()) |
@@ -1980,8 +2088,8 @@ static int serial8250_startup(struct uart_port *port) | |||
1980 | /* | 2088 | /* |
1981 | * Clear the interrupt registers. | 2089 | * Clear the interrupt registers. |
1982 | */ | 2090 | */ |
1983 | serial_port_in(port, UART_LSR); | 2091 | if (serial_port_in(port, UART_LSR) & UART_LSR_DR) |
1984 | serial_port_in(port, UART_RX); | 2092 | serial_port_in(port, UART_RX); |
1985 | serial_port_in(port, UART_IIR); | 2093 | serial_port_in(port, UART_IIR); |
1986 | serial_port_in(port, UART_MSR); | 2094 | serial_port_in(port, UART_MSR); |
1987 | 2095 | ||
@@ -1994,7 +2102,8 @@ static int serial8250_startup(struct uart_port *port) | |||
1994 | (serial_port_in(port, UART_LSR) == 0xff)) { | 2102 | (serial_port_in(port, UART_LSR) == 0xff)) { |
1995 | printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", | 2103 | printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n", |
1996 | serial_index(port)); | 2104 | serial_index(port)); |
1997 | return -ENODEV; | 2105 | retval = -ENODEV; |
2106 | goto out; | ||
1998 | } | 2107 | } |
1999 | 2108 | ||
2000 | /* | 2109 | /* |
@@ -2079,7 +2188,7 @@ static int serial8250_startup(struct uart_port *port) | |||
2079 | } else { | 2188 | } else { |
2080 | retval = serial_link_irq_chain(up); | 2189 | retval = serial_link_irq_chain(up); |
2081 | if (retval) | 2190 | if (retval) |
2082 | return retval; | 2191 | goto out; |
2083 | } | 2192 | } |
2084 | 2193 | ||
2085 | /* | 2194 | /* |
@@ -2141,8 +2250,8 @@ dont_test_tx_en: | |||
2141 | * saved flags to avoid getting false values from polling | 2250 | * saved flags to avoid getting false values from polling |
2142 | * routines or the previous session. | 2251 | * routines or the previous session. |
2143 | */ | 2252 | */ |
2144 | serial_port_in(port, UART_LSR); | 2253 | if (serial_port_in(port, UART_LSR) & UART_LSR_DR) |
2145 | serial_port_in(port, UART_RX); | 2254 | serial_port_in(port, UART_RX); |
2146 | serial_port_in(port, UART_IIR); | 2255 | serial_port_in(port, UART_IIR); |
2147 | serial_port_in(port, UART_MSR); | 2256 | serial_port_in(port, UART_MSR); |
2148 | up->lsr_saved_flags = 0; | 2257 | up->lsr_saved_flags = 0; |
@@ -2177,15 +2286,26 @@ dont_test_tx_en: | |||
2177 | outb_p(0x80, icp); | 2286 | outb_p(0x80, icp); |
2178 | inb_p(icp); | 2287 | inb_p(icp); |
2179 | } | 2288 | } |
2289 | retval = 0; | ||
2290 | out: | ||
2291 | serial8250_rpm_put(up); | ||
2292 | return retval; | ||
2293 | } | ||
2294 | EXPORT_SYMBOL_GPL(serial8250_do_startup); | ||
2180 | 2295 | ||
2181 | return 0; | 2296 | static int serial8250_startup(struct uart_port *port) |
2297 | { | ||
2298 | if (port->startup) | ||
2299 | return port->startup(port); | ||
2300 | return serial8250_do_startup(port); | ||
2182 | } | 2301 | } |
2183 | 2302 | ||
2184 | static void serial8250_shutdown(struct uart_port *port) | 2303 | void serial8250_do_shutdown(struct uart_port *port) |
2185 | { | 2304 | { |
2186 | struct uart_8250_port *up = up_to_u8250p(port); | 2305 | struct uart_8250_port *up = up_to_u8250p(port); |
2187 | unsigned long flags; | 2306 | unsigned long flags; |
2188 | 2307 | ||
2308 | serial8250_rpm_get(up); | ||
2189 | /* | 2309 | /* |
2190 | * Disable interrupts from this port | 2310 | * Disable interrupts from this port |
2191 | */ | 2311 | */ |
@@ -2224,13 +2344,24 @@ static void serial8250_shutdown(struct uart_port *port) | |||
2224 | * Read data port to reset things, and then unlink from | 2344 | * Read data port to reset things, and then unlink from |
2225 | * the IRQ chain. | 2345 | * the IRQ chain. |
2226 | */ | 2346 | */ |
2227 | serial_port_in(port, UART_RX); | 2347 | if (serial_port_in(port, UART_LSR) & UART_LSR_DR) |
2348 | serial_port_in(port, UART_RX); | ||
2349 | serial8250_rpm_put(up); | ||
2228 | 2350 | ||
2229 | del_timer_sync(&up->timer); | 2351 | del_timer_sync(&up->timer); |
2230 | up->timer.function = serial8250_timeout; | 2352 | up->timer.function = serial8250_timeout; |
2231 | if (port->irq) | 2353 | if (port->irq) |
2232 | serial_unlink_irq_chain(up); | 2354 | serial_unlink_irq_chain(up); |
2233 | } | 2355 | } |
2356 | EXPORT_SYMBOL_GPL(serial8250_do_shutdown); | ||
2357 | |||
2358 | static void serial8250_shutdown(struct uart_port *port) | ||
2359 | { | ||
2360 | if (port->shutdown) | ||
2361 | port->shutdown(port); | ||
2362 | else | ||
2363 | serial8250_do_shutdown(port); | ||
2364 | } | ||
2234 | 2365 | ||
2235 | static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) | 2366 | static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) |
2236 | { | 2367 | { |
@@ -2319,11 +2450,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2319 | * the trigger, or the MCR RTS bit is cleared. In the case where | 2450 | * the trigger, or the MCR RTS bit is cleared. In the case where |
2320 | * the remote UART is not using CTS auto flow control, we must | 2451 | * the remote UART is not using CTS auto flow control, we must |
2321 | * have sufficient FIFO entries for the latency of the remote | 2452 | * have sufficient FIFO entries for the latency of the remote |
2322 | * UART to respond. IOW, at least 32 bytes of FIFO. Also enable | 2453 | * UART to respond. IOW, at least 32 bytes of FIFO. |
2323 | * AFE if hw flow control is supported | ||
2324 | */ | 2454 | */ |
2325 | if ((up->capabilities & UART_CAP_AFE && (port->fifosize >= 32)) || | 2455 | if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) { |
2326 | (port->flags & UPF_HARD_FLOW)) { | ||
2327 | up->mcr &= ~UART_MCR_AFE; | 2456 | up->mcr &= ~UART_MCR_AFE; |
2328 | if (termios->c_cflag & CRTSCTS) | 2457 | if (termios->c_cflag & CRTSCTS) |
2329 | up->mcr |= UART_MCR_AFE; | 2458 | up->mcr |= UART_MCR_AFE; |
@@ -2333,6 +2462,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2333 | * Ok, we're now changing the port state. Do it with | 2462 | * Ok, we're now changing the port state. Do it with |
2334 | * interrupts disabled. | 2463 | * interrupts disabled. |
2335 | */ | 2464 | */ |
2465 | serial8250_rpm_get(up); | ||
2336 | spin_lock_irqsave(&port->lock, flags); | 2466 | spin_lock_irqsave(&port->lock, flags); |
2337 | 2467 | ||
2338 | /* | 2468 | /* |
@@ -2454,6 +2584,8 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2454 | } | 2584 | } |
2455 | serial8250_set_mctrl(port, port->mctrl); | 2585 | serial8250_set_mctrl(port, port->mctrl); |
2456 | spin_unlock_irqrestore(&port->lock, flags); | 2586 | spin_unlock_irqrestore(&port->lock, flags); |
2587 | serial8250_rpm_put(up); | ||
2588 | |||
2457 | /* Don't rewrite B0 */ | 2589 | /* Don't rewrite B0 */ |
2458 | if (tty_termios_baud_rate(termios)) | 2590 | if (tty_termios_baud_rate(termios)) |
2459 | tty_termios_encode_baud_rate(termios, baud, baud); | 2591 | tty_termios_encode_baud_rate(termios, baud, baud); |
@@ -2843,6 +2975,42 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
2843 | return 0; | 2975 | return 0; |
2844 | } | 2976 | } |
2845 | 2977 | ||
2978 | static int serial8250_ioctl(struct uart_port *port, unsigned int cmd, | ||
2979 | unsigned long arg) | ||
2980 | { | ||
2981 | struct uart_8250_port *up = | ||
2982 | container_of(port, struct uart_8250_port, port); | ||
2983 | int ret; | ||
2984 | struct serial_rs485 rs485_config; | ||
2985 | |||
2986 | if (!up->rs485_config) | ||
2987 | return -ENOIOCTLCMD; | ||
2988 | |||
2989 | switch (cmd) { | ||
2990 | case TIOCSRS485: | ||
2991 | if (copy_from_user(&rs485_config, (void __user *)arg, | ||
2992 | sizeof(rs485_config))) | ||
2993 | return -EFAULT; | ||
2994 | |||
2995 | ret = up->rs485_config(up, &rs485_config); | ||
2996 | if (ret) | ||
2997 | return ret; | ||
2998 | |||
2999 | memcpy(&up->rs485, &rs485_config, sizeof(rs485_config)); | ||
3000 | |||
3001 | return 0; | ||
3002 | case TIOCGRS485: | ||
3003 | if (copy_to_user((void __user *)arg, &up->rs485, | ||
3004 | sizeof(up->rs485))) | ||
3005 | return -EFAULT; | ||
3006 | return 0; | ||
3007 | default: | ||
3008 | break; | ||
3009 | } | ||
3010 | |||
3011 | return -ENOIOCTLCMD; | ||
3012 | } | ||
3013 | |||
2846 | static const char * | 3014 | static const char * |
2847 | serial8250_type(struct uart_port *port) | 3015 | serial8250_type(struct uart_port *port) |
2848 | { | 3016 | { |
@@ -2859,6 +3027,8 @@ static struct uart_ops serial8250_pops = { | |||
2859 | .get_mctrl = serial8250_get_mctrl, | 3027 | .get_mctrl = serial8250_get_mctrl, |
2860 | .stop_tx = serial8250_stop_tx, | 3028 | .stop_tx = serial8250_stop_tx, |
2861 | .start_tx = serial8250_start_tx, | 3029 | .start_tx = serial8250_start_tx, |
3030 | .throttle = serial8250_throttle, | ||
3031 | .unthrottle = serial8250_unthrottle, | ||
2862 | .stop_rx = serial8250_stop_rx, | 3032 | .stop_rx = serial8250_stop_rx, |
2863 | .enable_ms = serial8250_enable_ms, | 3033 | .enable_ms = serial8250_enable_ms, |
2864 | .break_ctl = serial8250_break_ctl, | 3034 | .break_ctl = serial8250_break_ctl, |
@@ -2872,6 +3042,7 @@ static struct uart_ops serial8250_pops = { | |||
2872 | .request_port = serial8250_request_port, | 3042 | .request_port = serial8250_request_port, |
2873 | .config_port = serial8250_config_port, | 3043 | .config_port = serial8250_config_port, |
2874 | .verify_port = serial8250_verify_port, | 3044 | .verify_port = serial8250_verify_port, |
3045 | .ioctl = serial8250_ioctl, | ||
2875 | #ifdef CONFIG_CONSOLE_POLL | 3046 | #ifdef CONFIG_CONSOLE_POLL |
2876 | .poll_get_char = serial8250_get_poll_char, | 3047 | .poll_get_char = serial8250_get_poll_char, |
2877 | .poll_put_char = serial8250_put_poll_char, | 3048 | .poll_put_char = serial8250_put_poll_char, |
@@ -2880,6 +3051,24 @@ static struct uart_ops serial8250_pops = { | |||
2880 | 3051 | ||
2881 | static struct uart_8250_port serial8250_ports[UART_NR]; | 3052 | static struct uart_8250_port serial8250_ports[UART_NR]; |
2882 | 3053 | ||
3054 | /** | ||
3055 | * serial8250_get_port - retrieve struct uart_8250_port | ||
3056 | * @line: serial line number | ||
3057 | * | ||
3058 | * This function retrieves struct uart_8250_port for the specific line. | ||
3059 | * This struct *must* *not* be used to perform a 8250 or serial core operation | ||
3060 | * which is not accessible otherwise. Its only purpose is to make the struct | ||
3061 | * accessible to the runtime-pm callbacks for context suspend/restore. | ||
3062 | * The lock assumption made here is none because runtime-pm suspend/resume | ||
3063 | * callbacks should not be invoked if there is any operation performed on the | ||
3064 | * port. | ||
3065 | */ | ||
3066 | struct uart_8250_port *serial8250_get_port(int line) | ||
3067 | { | ||
3068 | return &serial8250_ports[line]; | ||
3069 | } | ||
3070 | EXPORT_SYMBOL_GPL(serial8250_get_port); | ||
3071 | |||
2883 | static void (*serial8250_isa_config)(int port, struct uart_port *up, | 3072 | static void (*serial8250_isa_config)(int port, struct uart_port *up, |
2884 | unsigned short *capabilities); | 3073 | unsigned short *capabilities); |
2885 | 3074 | ||
@@ -3007,6 +3196,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
3007 | 3196 | ||
3008 | touch_nmi_watchdog(); | 3197 | touch_nmi_watchdog(); |
3009 | 3198 | ||
3199 | serial8250_rpm_get(up); | ||
3200 | |||
3010 | if (port->sysrq || oops_in_progress) | 3201 | if (port->sysrq || oops_in_progress) |
3011 | locked = spin_trylock_irqsave(&port->lock, flags); | 3202 | locked = spin_trylock_irqsave(&port->lock, flags); |
3012 | else | 3203 | else |
@@ -3043,6 +3234,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
3043 | 3234 | ||
3044 | if (locked) | 3235 | if (locked) |
3045 | spin_unlock_irqrestore(&port->lock, flags); | 3236 | spin_unlock_irqrestore(&port->lock, flags); |
3237 | serial8250_rpm_put(up); | ||
3046 | } | 3238 | } |
3047 | 3239 | ||
3048 | static int __init serial8250_console_setup(struct console *co, char *options) | 3240 | static int __init serial8250_console_setup(struct console *co, char *options) |
@@ -3324,6 +3516,11 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * | |||
3324 | if (uart_match_port(&serial8250_ports[i].port, port)) | 3516 | if (uart_match_port(&serial8250_ports[i].port, port)) |
3325 | return &serial8250_ports[i]; | 3517 | return &serial8250_ports[i]; |
3326 | 3518 | ||
3519 | /* try line number first if still available */ | ||
3520 | i = port->line; | ||
3521 | if (i < nr_uarts && serial8250_ports[i].port.type == PORT_UNKNOWN && | ||
3522 | serial8250_ports[i].port.iobase == 0) | ||
3523 | return &serial8250_ports[i]; | ||
3327 | /* | 3524 | /* |
3328 | * We didn't find a matching entry, so look for the first | 3525 | * We didn't find a matching entry, so look for the first |
3329 | * free entry. We look for one which hasn't been previously | 3526 | * free entry. We look for one which hasn't been previously |
@@ -3388,6 +3585,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3388 | uart->port.fifosize = up->port.fifosize; | 3585 | uart->port.fifosize = up->port.fifosize; |
3389 | uart->tx_loadsz = up->tx_loadsz; | 3586 | uart->tx_loadsz = up->tx_loadsz; |
3390 | uart->capabilities = up->capabilities; | 3587 | uart->capabilities = up->capabilities; |
3588 | uart->rs485_config = up->rs485_config; | ||
3589 | uart->rs485 = up->rs485; | ||
3590 | uart->port.throttle = up->port.throttle; | ||
3591 | uart->port.unthrottle = up->port.unthrottle; | ||
3391 | 3592 | ||
3392 | /* Take tx_loadsz from fifosize if it wasn't set separately */ | 3593 | /* Take tx_loadsz from fifosize if it wasn't set separately */ |
3393 | if (uart->port.fifosize && !uart->tx_loadsz) | 3594 | if (uart->port.fifosize && !uart->tx_loadsz) |
@@ -3410,6 +3611,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3410 | /* Possibly override set_termios call */ | 3611 | /* Possibly override set_termios call */ |
3411 | if (up->port.set_termios) | 3612 | if (up->port.set_termios) |
3412 | uart->port.set_termios = up->port.set_termios; | 3613 | uart->port.set_termios = up->port.set_termios; |
3614 | if (up->port.startup) | ||
3615 | uart->port.startup = up->port.startup; | ||
3616 | if (up->port.shutdown) | ||
3617 | uart->port.shutdown = up->port.shutdown; | ||
3413 | if (up->port.pm) | 3618 | if (up->port.pm) |
3414 | uart->port.pm = up->port.pm; | 3619 | uart->port.pm = up->port.pm; |
3415 | if (up->port.handle_break) | 3620 | if (up->port.handle_break) |
diff --git a/drivers/tty/serial/8250/8250_fintek.c b/drivers/tty/serial/8250/8250_fintek.c new file mode 100644 index 000000000000..1bb28cb69493 --- /dev/null +++ b/drivers/tty/serial/8250/8250_fintek.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* | ||
2 | * Probe for F81216A LPC to 4 UART | ||
3 | * | ||
4 | * Based on drivers/tty/serial/8250_pnp.c, by Russell King, et al | ||
5 | * | ||
6 | * Copyright (C) 2014 Ricardo Ribalda, Qtechnology A/S | ||
7 | * | ||
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 as published by | ||
11 | * the Free Software Foundation; either version 2 of the License. | ||
12 | */ | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/pci.h> | ||
15 | #include <linux/pnp.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/serial_core.h> | ||
18 | #include "8250.h" | ||
19 | |||
20 | #define ADDR_PORT 0x4E | ||
21 | #define DATA_PORT 0x4F | ||
22 | #define ENTRY_KEY 0x77 | ||
23 | #define EXIT_KEY 0xAA | ||
24 | #define CHIP_ID1 0x20 | ||
25 | #define CHIP_ID1_VAL 0x02 | ||
26 | #define CHIP_ID2 0x21 | ||
27 | #define CHIP_ID2_VAL 0x16 | ||
28 | #define VENDOR_ID1 0x23 | ||
29 | #define VENDOR_ID1_VAL 0x19 | ||
30 | #define VENDOR_ID2 0x24 | ||
31 | #define VENDOR_ID2_VAL 0x34 | ||
32 | #define LDN 0x7 | ||
33 | |||
34 | #define RS485 0xF0 | ||
35 | #define RTS_INVERT BIT(5) | ||
36 | #define RS485_URA BIT(4) | ||
37 | #define RXW4C_IRA BIT(3) | ||
38 | #define TXW4C_IRA BIT(2) | ||
39 | |||
40 | #define DRIVER_NAME "8250_fintek" | ||
41 | |||
42 | static int fintek_8250_enter_key(void){ | ||
43 | |||
44 | if (!request_muxed_region(ADDR_PORT, 2, DRIVER_NAME)) | ||
45 | return -EBUSY; | ||
46 | |||
47 | outb(ENTRY_KEY, ADDR_PORT); | ||
48 | outb(ENTRY_KEY, ADDR_PORT); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static void fintek_8250_exit_key(void){ | ||
53 | |||
54 | outb(EXIT_KEY, ADDR_PORT); | ||
55 | release_region(ADDR_PORT, 2); | ||
56 | } | ||
57 | |||
58 | static int fintek_8250_get_index(resource_size_t base_addr) | ||
59 | { | ||
60 | resource_size_t base[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8}; | ||
61 | int i; | ||
62 | |||
63 | for (i = 0; i < ARRAY_SIZE(base); i++) | ||
64 | if (base_addr == base[i]) | ||
65 | return i; | ||
66 | |||
67 | return -ENODEV; | ||
68 | } | ||
69 | |||
70 | static int fintek_8250_check_id(void) | ||
71 | { | ||
72 | |||
73 | outb(CHIP_ID1, ADDR_PORT); | ||
74 | if (inb(DATA_PORT) != CHIP_ID1_VAL) | ||
75 | return -ENODEV; | ||
76 | |||
77 | outb(CHIP_ID2, ADDR_PORT); | ||
78 | if (inb(DATA_PORT) != CHIP_ID2_VAL) | ||
79 | return -ENODEV; | ||
80 | |||
81 | outb(VENDOR_ID1, ADDR_PORT); | ||
82 | if (inb(DATA_PORT) != VENDOR_ID1_VAL) | ||
83 | return -ENODEV; | ||
84 | |||
85 | outb(VENDOR_ID2, ADDR_PORT); | ||
86 | if (inb(DATA_PORT) != VENDOR_ID2_VAL) | ||
87 | return -ENODEV; | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int fintek_8250_rs4850_config(struct uart_8250_port *uart, | ||
93 | struct serial_rs485 *rs485) | ||
94 | { | ||
95 | uint8_t config = 0; | ||
96 | int index = fintek_8250_get_index(uart->port.iobase); | ||
97 | |||
98 | if (index < 0) | ||
99 | return -EINVAL; | ||
100 | |||
101 | if (rs485->flags & SER_RS485_ENABLED) | ||
102 | memset(rs485->padding, 0, sizeof(rs485->padding)); | ||
103 | else | ||
104 | memset(rs485, 0, sizeof(*rs485)); | ||
105 | |||
106 | rs485->flags &= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | | ||
107 | SER_RS485_RTS_AFTER_SEND; | ||
108 | |||
109 | if (rs485->delay_rts_before_send) { | ||
110 | rs485->delay_rts_before_send = 1; | ||
111 | config |= TXW4C_IRA; | ||
112 | } | ||
113 | |||
114 | if (rs485->delay_rts_after_send) { | ||
115 | rs485->delay_rts_after_send = 1; | ||
116 | config |= RXW4C_IRA; | ||
117 | } | ||
118 | |||
119 | if ((!!(rs485->flags & SER_RS485_RTS_ON_SEND)) == | ||
120 | (!!(rs485->flags & SER_RS485_RTS_AFTER_SEND))) | ||
121 | rs485->flags &= SER_RS485_ENABLED; | ||
122 | else | ||
123 | config |= RS485_URA; | ||
124 | |||
125 | if (rs485->flags & SER_RS485_RTS_ON_SEND) | ||
126 | config |= RTS_INVERT; | ||
127 | |||
128 | if (fintek_8250_enter_key()) | ||
129 | return -EBUSY; | ||
130 | |||
131 | outb(LDN, ADDR_PORT); | ||
132 | outb(index, DATA_PORT); | ||
133 | outb(RS485, ADDR_PORT); | ||
134 | outb(config, DATA_PORT); | ||
135 | fintek_8250_exit_key(); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int | ||
141 | fintek_8250_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | ||
142 | { | ||
143 | int line; | ||
144 | struct uart_8250_port uart; | ||
145 | int ret; | ||
146 | |||
147 | if (!pnp_port_valid(dev, 0)) | ||
148 | return -ENODEV; | ||
149 | |||
150 | if (fintek_8250_get_index(pnp_port_start(dev, 0)) < 0) | ||
151 | return -ENODEV; | ||
152 | |||
153 | /* Enable configuration registers*/ | ||
154 | if (fintek_8250_enter_key()) | ||
155 | return -EBUSY; | ||
156 | |||
157 | /*Check ID*/ | ||
158 | ret = fintek_8250_check_id(); | ||
159 | fintek_8250_exit_key(); | ||
160 | if (ret) | ||
161 | return ret; | ||
162 | |||
163 | memset(&uart, 0, sizeof(uart)); | ||
164 | if (!pnp_irq_valid(dev, 0)) | ||
165 | return -ENODEV; | ||
166 | uart.port.irq = pnp_irq(dev, 0); | ||
167 | uart.port.iobase = pnp_port_start(dev, 0); | ||
168 | uart.port.iotype = UPIO_PORT; | ||
169 | uart.rs485_config = fintek_8250_rs4850_config; | ||
170 | |||
171 | uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | ||
172 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) | ||
173 | uart.port.flags |= UPF_SHARE_IRQ; | ||
174 | uart.port.uartclk = 1843200; | ||
175 | uart.port.dev = &dev->dev; | ||
176 | |||
177 | line = serial8250_register_8250_port(&uart); | ||
178 | if (line < 0) | ||
179 | return -ENODEV; | ||
180 | |||
181 | pnp_set_drvdata(dev, (void *)((long)line + 1)); | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static void fintek_8250_remove(struct pnp_dev *dev) | ||
186 | { | ||
187 | long line = (long)pnp_get_drvdata(dev); | ||
188 | |||
189 | if (line) | ||
190 | serial8250_unregister_port(line - 1); | ||
191 | } | ||
192 | |||
193 | #ifdef CONFIG_PM | ||
194 | static int fintek_8250_suspend(struct pnp_dev *dev, pm_message_t state) | ||
195 | { | ||
196 | long line = (long)pnp_get_drvdata(dev); | ||
197 | |||
198 | if (!line) | ||
199 | return -ENODEV; | ||
200 | serial8250_suspend_port(line - 1); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int fintek_8250_resume(struct pnp_dev *dev) | ||
205 | { | ||
206 | long line = (long)pnp_get_drvdata(dev); | ||
207 | |||
208 | if (!line) | ||
209 | return -ENODEV; | ||
210 | serial8250_resume_port(line - 1); | ||
211 | return 0; | ||
212 | } | ||
213 | #else | ||
214 | #define fintek_8250_suspend NULL | ||
215 | #define fintek_8250_resume NULL | ||
216 | #endif /* CONFIG_PM */ | ||
217 | |||
218 | static const struct pnp_device_id fintek_dev_table[] = { | ||
219 | /* Qtechnology Panel PC / IO1000 */ | ||
220 | { "PNP0501"}, | ||
221 | {} | ||
222 | }; | ||
223 | |||
224 | MODULE_DEVICE_TABLE(pnp, fintek_dev_table); | ||
225 | |||
226 | static struct pnp_driver fintek_8250_driver = { | ||
227 | .name = DRIVER_NAME, | ||
228 | .probe = fintek_8250_probe, | ||
229 | .remove = fintek_8250_remove, | ||
230 | .suspend = fintek_8250_suspend, | ||
231 | .resume = fintek_8250_resume, | ||
232 | .id_table = fintek_dev_table, | ||
233 | }; | ||
234 | |||
235 | static int fintek_8250_init(void) | ||
236 | { | ||
237 | return pnp_register_driver(&fintek_8250_driver); | ||
238 | } | ||
239 | module_init(fintek_8250_init); | ||
240 | |||
241 | static void fintek_8250_exit(void) | ||
242 | { | ||
243 | pnp_unregister_driver(&fintek_8250_driver); | ||
244 | } | ||
245 | module_exit(fintek_8250_exit); | ||
246 | |||
247 | MODULE_DESCRIPTION("Fintek F812164 module"); | ||
248 | MODULE_AUTHOR("Ricardo Ribalda <ricardo.ribalda@gmail.com>"); | ||
249 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index 5bdaf271d395..afffe4d1f034 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include "8250.h" | 21 | #include "8250.h" |
22 | 22 | ||
23 | #if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) | 23 | #if !defined(CONFIG_HPDCA) && !defined(CONFIG_HPAPCI) |
24 | #warning CONFIG_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure? | 24 | #warning CONFIG_SERIAL_8250 defined but neither CONFIG_HPDCA nor CONFIG_HPAPCI defined, are you sure? |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef CONFIG_HPAPCI | 27 | #ifdef CONFIG_HPAPCI |
diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c new file mode 100644 index 000000000000..8f37d57165ec --- /dev/null +++ b/drivers/tty/serial/8250/8250_mtk.c | |||
@@ -0,0 +1,294 @@ | |||
1 | /* | ||
2 | * Mediatek 8250 driver. | ||
3 | * | ||
4 | * Copyright (c) 2014 MundoReader S.L. | ||
5 | * Author: Matthias Brugger <matthias.bgg@gmail.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <linux/of_platform.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/pm_runtime.h> | ||
24 | #include <linux/serial_8250.h> | ||
25 | #include <linux/serial_reg.h> | ||
26 | |||
27 | #include "8250.h" | ||
28 | |||
29 | #define UART_MTK_HIGHS 0x09 /* Highspeed register */ | ||
30 | #define UART_MTK_SAMPLE_COUNT 0x0a /* Sample count register */ | ||
31 | #define UART_MTK_SAMPLE_POINT 0x0b /* Sample point register */ | ||
32 | #define MTK_UART_RATE_FIX 0x0d /* UART Rate Fix Register */ | ||
33 | |||
34 | struct mtk8250_data { | ||
35 | int line; | ||
36 | struct clk *uart_clk; | ||
37 | }; | ||
38 | |||
39 | static void | ||
40 | mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, | ||
41 | struct ktermios *old) | ||
42 | { | ||
43 | unsigned long flags; | ||
44 | unsigned int baud, quot; | ||
45 | |||
46 | struct uart_8250_port *up = | ||
47 | container_of(port, struct uart_8250_port, port); | ||
48 | |||
49 | serial8250_do_set_termios(port, termios, old); | ||
50 | |||
51 | /* | ||
52 | * Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS) | ||
53 | * | ||
54 | * We need to recalcualte the quot register, as the claculation depends | ||
55 | * on the vaule in the highspeed register. | ||
56 | * | ||
57 | * Some baudrates are not supported by the chip, so we use the next | ||
58 | * lower rate supported and update termios c_flag. | ||
59 | * | ||
60 | * If highspeed register is set to 3, we need to specify sample count | ||
61 | * and sample point to increase accuracy. If not, we reset the | ||
62 | * registers to their default values. | ||
63 | */ | ||
64 | baud = uart_get_baud_rate(port, termios, old, | ||
65 | port->uartclk / 16 / 0xffff, | ||
66 | port->uartclk / 16); | ||
67 | |||
68 | if (baud <= 115200) { | ||
69 | serial_port_out(port, UART_MTK_HIGHS, 0x0); | ||
70 | quot = uart_get_divisor(port, baud); | ||
71 | } else if (baud <= 576000) { | ||
72 | serial_port_out(port, UART_MTK_HIGHS, 0x2); | ||
73 | |||
74 | /* Set to next lower baudrate supported */ | ||
75 | if ((baud == 500000) || (baud == 576000)) | ||
76 | baud = 460800; | ||
77 | quot = DIV_ROUND_CLOSEST(port->uartclk, 4 * baud); | ||
78 | } else { | ||
79 | serial_port_out(port, UART_MTK_HIGHS, 0x3); | ||
80 | |||
81 | /* Set to highest baudrate supported */ | ||
82 | if (baud >= 1152000) | ||
83 | baud = 921600; | ||
84 | quot = DIV_ROUND_CLOSEST(port->uartclk, 256 * baud); | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * Ok, we're now changing the port state. Do it with | ||
89 | * interrupts disabled. | ||
90 | */ | ||
91 | spin_lock_irqsave(&port->lock, flags); | ||
92 | |||
93 | /* set DLAB we have cval saved in up->lcr from the call to the core */ | ||
94 | serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); | ||
95 | serial_dl_write(up, quot); | ||
96 | |||
97 | /* reset DLAB */ | ||
98 | serial_port_out(port, UART_LCR, up->lcr); | ||
99 | |||
100 | if (baud > 460800) { | ||
101 | unsigned int tmp; | ||
102 | |||
103 | tmp = DIV_ROUND_CLOSEST(port->uartclk, quot * baud); | ||
104 | serial_port_out(port, UART_MTK_SAMPLE_COUNT, tmp - 1); | ||
105 | serial_port_out(port, UART_MTK_SAMPLE_POINT, | ||
106 | (tmp - 2) >> 1); | ||
107 | } else { | ||
108 | serial_port_out(port, UART_MTK_SAMPLE_COUNT, 0x00); | ||
109 | serial_port_out(port, UART_MTK_SAMPLE_POINT, 0xff); | ||
110 | } | ||
111 | |||
112 | spin_unlock_irqrestore(&port->lock, flags); | ||
113 | /* Don't rewrite B0 */ | ||
114 | if (tty_termios_baud_rate(termios)) | ||
115 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
116 | } | ||
117 | |||
118 | static void | ||
119 | mtk8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old) | ||
120 | { | ||
121 | if (!state) | ||
122 | pm_runtime_get_sync(port->dev); | ||
123 | |||
124 | serial8250_do_pm(port, state, old); | ||
125 | |||
126 | if (state) | ||
127 | pm_runtime_put_sync_suspend(port->dev); | ||
128 | } | ||
129 | |||
130 | static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, | ||
131 | struct mtk8250_data *data) | ||
132 | { | ||
133 | int err; | ||
134 | struct device_node *np = pdev->dev.of_node; | ||
135 | |||
136 | data->uart_clk = of_clk_get(np, 0); | ||
137 | if (IS_ERR(data->uart_clk)) { | ||
138 | dev_warn(&pdev->dev, "Can't get timer clock\n"); | ||
139 | return PTR_ERR(data->uart_clk); | ||
140 | } | ||
141 | |||
142 | err = clk_prepare_enable(data->uart_clk); | ||
143 | if (err) { | ||
144 | dev_warn(&pdev->dev, "Can't prepare clock\n"); | ||
145 | clk_put(data->uart_clk); | ||
146 | return err; | ||
147 | } | ||
148 | p->uartclk = clk_get_rate(data->uart_clk); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int mtk8250_probe(struct platform_device *pdev) | ||
154 | { | ||
155 | struct uart_8250_port uart = {}; | ||
156 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
157 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
158 | struct mtk8250_data *data; | ||
159 | int err; | ||
160 | |||
161 | if (!regs || !irq) { | ||
162 | dev_err(&pdev->dev, "no registers/irq defined\n"); | ||
163 | return -EINVAL; | ||
164 | } | ||
165 | |||
166 | uart.port.membase = devm_ioremap(&pdev->dev, regs->start, | ||
167 | resource_size(regs)); | ||
168 | if (!uart.port.membase) | ||
169 | return -ENOMEM; | ||
170 | |||
171 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
172 | if (!data) | ||
173 | return -ENOMEM; | ||
174 | |||
175 | if (pdev->dev.of_node) { | ||
176 | err = mtk8250_probe_of(pdev, &uart.port, data); | ||
177 | if (err) | ||
178 | return err; | ||
179 | } else | ||
180 | return -ENODEV; | ||
181 | |||
182 | spin_lock_init(&uart.port.lock); | ||
183 | uart.port.mapbase = regs->start; | ||
184 | uart.port.irq = irq->start; | ||
185 | uart.port.pm = mtk8250_do_pm; | ||
186 | uart.port.type = PORT_16550; | ||
187 | uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; | ||
188 | uart.port.dev = &pdev->dev; | ||
189 | uart.port.iotype = UPIO_MEM32; | ||
190 | uart.port.regshift = 2; | ||
191 | uart.port.private_data = data; | ||
192 | uart.port.set_termios = mtk8250_set_termios; | ||
193 | |||
194 | /* Disable Rate Fix function */ | ||
195 | writel(0x0, uart.port.membase + | ||
196 | (MTK_UART_RATE_FIX << uart.port.regshift)); | ||
197 | |||
198 | data->line = serial8250_register_8250_port(&uart); | ||
199 | if (data->line < 0) | ||
200 | return data->line; | ||
201 | |||
202 | platform_set_drvdata(pdev, data); | ||
203 | |||
204 | pm_runtime_set_active(&pdev->dev); | ||
205 | pm_runtime_enable(&pdev->dev); | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static int mtk8250_remove(struct platform_device *pdev) | ||
211 | { | ||
212 | struct mtk8250_data *data = platform_get_drvdata(pdev); | ||
213 | |||
214 | pm_runtime_get_sync(&pdev->dev); | ||
215 | |||
216 | serial8250_unregister_port(data->line); | ||
217 | if (!IS_ERR(data->uart_clk)) { | ||
218 | clk_disable_unprepare(data->uart_clk); | ||
219 | clk_put(data->uart_clk); | ||
220 | } | ||
221 | |||
222 | pm_runtime_disable(&pdev->dev); | ||
223 | pm_runtime_put_noidle(&pdev->dev); | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | #ifdef CONFIG_PM_SLEEP | ||
228 | static int mtk8250_suspend(struct device *dev) | ||
229 | { | ||
230 | struct mtk8250_data *data = dev_get_drvdata(dev); | ||
231 | |||
232 | serial8250_suspend_port(data->line); | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static int mtk8250_resume(struct device *dev) | ||
238 | { | ||
239 | struct mtk8250_data *data = dev_get_drvdata(dev); | ||
240 | |||
241 | serial8250_resume_port(data->line); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | #endif /* CONFIG_PM_SLEEP */ | ||
246 | |||
247 | #ifdef CONFIG_PM_RUNTIME | ||
248 | static int mtk8250_runtime_suspend(struct device *dev) | ||
249 | { | ||
250 | struct mtk8250_data *data = dev_get_drvdata(dev); | ||
251 | |||
252 | if (!IS_ERR(data->uart_clk)) | ||
253 | clk_disable_unprepare(data->uart_clk); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int mtk8250_runtime_resume(struct device *dev) | ||
259 | { | ||
260 | struct mtk8250_data *data = dev_get_drvdata(dev); | ||
261 | |||
262 | if (!IS_ERR(data->uart_clk)) | ||
263 | clk_prepare_enable(data->uart_clk); | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | #endif | ||
268 | |||
269 | static const struct dev_pm_ops mtk8250_pm_ops = { | ||
270 | SET_SYSTEM_SLEEP_PM_OPS(mtk8250_suspend, mtk8250_resume) | ||
271 | SET_RUNTIME_PM_OPS(mtk8250_runtime_suspend, mtk8250_runtime_resume, | ||
272 | NULL) | ||
273 | }; | ||
274 | |||
275 | static const struct of_device_id mtk8250_of_match[] = { | ||
276 | { .compatible = "mediatek,mt6577-uart" }, | ||
277 | { /* Sentinel */ } | ||
278 | }; | ||
279 | MODULE_DEVICE_TABLE(of, mtk8250_of_match); | ||
280 | |||
281 | static struct platform_driver mtk8250_platform_driver = { | ||
282 | .driver = { | ||
283 | .name = "mt6577-uart", | ||
284 | .pm = &mtk8250_pm_ops, | ||
285 | .of_match_table = mtk8250_of_match, | ||
286 | }, | ||
287 | .probe = mtk8250_probe, | ||
288 | .remove = mtk8250_remove, | ||
289 | }; | ||
290 | module_platform_driver(mtk8250_platform_driver); | ||
291 | |||
292 | MODULE_AUTHOR("Matthias Brugger"); | ||
293 | MODULE_LICENSE("GPL"); | ||
294 | MODULE_DESCRIPTION("Mediatek 8250 serial port driver"); | ||
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 61830b1792eb..4f1cd296f1b1 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1355,9 +1355,6 @@ ce4100_serial_setup(struct serial_private *priv, | |||
1355 | #define BYT_PRV_CLK_N_VAL_SHIFT 16 | 1355 | #define BYT_PRV_CLK_N_VAL_SHIFT 16 |
1356 | #define BYT_PRV_CLK_UPDATE (1 << 31) | 1356 | #define BYT_PRV_CLK_UPDATE (1 << 31) |
1357 | 1357 | ||
1358 | #define BYT_GENERAL_REG 0x808 | ||
1359 | #define BYT_GENERAL_DIS_RTS_N_OVERRIDE (1 << 3) | ||
1360 | |||
1361 | #define BYT_TX_OVF_INT 0x820 | 1358 | #define BYT_TX_OVF_INT 0x820 |
1362 | #define BYT_TX_OVF_INT_MASK (1 << 1) | 1359 | #define BYT_TX_OVF_INT_MASK (1 << 1) |
1363 | 1360 | ||
@@ -1412,16 +1409,6 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios, | |||
1412 | reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE; | 1409 | reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE; |
1413 | writel(reg, p->membase + BYT_PRV_CLK); | 1410 | writel(reg, p->membase + BYT_PRV_CLK); |
1414 | 1411 | ||
1415 | /* | ||
1416 | * If auto-handshake mechanism is not enabled, | ||
1417 | * disable rts_n override | ||
1418 | */ | ||
1419 | reg = readl(p->membase + BYT_GENERAL_REG); | ||
1420 | reg &= ~BYT_GENERAL_DIS_RTS_N_OVERRIDE; | ||
1421 | if (termios->c_cflag & CRTSCTS) | ||
1422 | reg |= BYT_GENERAL_DIS_RTS_N_OVERRIDE; | ||
1423 | writel(reg, p->membase + BYT_GENERAL_REG); | ||
1424 | |||
1425 | serial8250_do_set_termios(p, termios, old); | 1412 | serial8250_do_set_termios(p, termios, old); |
1426 | } | 1413 | } |
1427 | 1414 | ||
@@ -1788,6 +1775,7 @@ pci_wch_ch353_setup(struct serial_private *priv, | |||
1788 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 | 1775 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 |
1789 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a | 1776 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a |
1790 | #define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e | 1777 | #define PCI_DEVICE_ID_AMCC_ADDIDATA_APCI7800 0x818e |
1778 | #define PCI_DEVICE_ID_INTEL_QRK_UART 0x0936 | ||
1791 | 1779 | ||
1792 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 | 1780 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 |
1793 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 | 1781 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 |
@@ -1898,6 +1886,13 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1898 | .subdevice = PCI_ANY_ID, | 1886 | .subdevice = PCI_ANY_ID, |
1899 | .setup = byt_serial_setup, | 1887 | .setup = byt_serial_setup, |
1900 | }, | 1888 | }, |
1889 | { | ||
1890 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1891 | .device = PCI_DEVICE_ID_INTEL_QRK_UART, | ||
1892 | .subvendor = PCI_ANY_ID, | ||
1893 | .subdevice = PCI_ANY_ID, | ||
1894 | .setup = pci_default_setup, | ||
1895 | }, | ||
1901 | /* | 1896 | /* |
1902 | * ITE | 1897 | * ITE |
1903 | */ | 1898 | */ |
@@ -2740,6 +2735,7 @@ enum pci_board_num_t { | |||
2740 | pbn_ADDIDATA_PCIe_8_3906250, | 2735 | pbn_ADDIDATA_PCIe_8_3906250, |
2741 | pbn_ce4100_1_115200, | 2736 | pbn_ce4100_1_115200, |
2742 | pbn_byt, | 2737 | pbn_byt, |
2738 | pbn_qrk, | ||
2743 | pbn_omegapci, | 2739 | pbn_omegapci, |
2744 | pbn_NETMOS9900_2s_115200, | 2740 | pbn_NETMOS9900_2s_115200, |
2745 | pbn_brcm_trumanage, | 2741 | pbn_brcm_trumanage, |
@@ -3490,6 +3486,12 @@ static struct pciserial_board pci_boards[] = { | |||
3490 | .uart_offset = 0x80, | 3486 | .uart_offset = 0x80, |
3491 | .reg_shift = 2, | 3487 | .reg_shift = 2, |
3492 | }, | 3488 | }, |
3489 | [pbn_qrk] = { | ||
3490 | .flags = FL_BASE0, | ||
3491 | .num_ports = 1, | ||
3492 | .base_baud = 2764800, | ||
3493 | .reg_shift = 2, | ||
3494 | }, | ||
3493 | [pbn_omegapci] = { | 3495 | [pbn_omegapci] = { |
3494 | .flags = FL_BASE0, | 3496 | .flags = FL_BASE0, |
3495 | .num_ports = 8, | 3497 | .num_ports = 8, |
@@ -5192,6 +5194,12 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
5192 | pbn_byt }, | 5194 | pbn_byt }, |
5193 | 5195 | ||
5194 | /* | 5196 | /* |
5197 | * Intel Quark x1000 | ||
5198 | */ | ||
5199 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_UART, | ||
5200 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
5201 | pbn_qrk }, | ||
5202 | /* | ||
5195 | * Cronyx Omega PCI | 5203 | * Cronyx Omega PCI |
5196 | */ | 5204 | */ |
5197 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA, | 5205 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA, |
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 349ee598b34c..21eca79224e4 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -298,3 +298,18 @@ config SERIAL_8250_RT288X | |||
298 | If you have a Ralink RT288x/RT305x SoC based board and want to use the | 298 | If you have a Ralink RT288x/RT305x SoC based board and want to use the |
299 | serial port, say Y to this option. The driver can handle up to 2 serial | 299 | serial port, say Y to this option. The driver can handle up to 2 serial |
300 | ports. If unsure, say N. | 300 | ports. If unsure, say N. |
301 | |||
302 | config SERIAL_8250_FINTEK | ||
303 | tristate "Support for Fintek F81216A LPC to 4 UART" | ||
304 | depends on SERIAL_8250 && PNP | ||
305 | help | ||
306 | Selecting this option will add support for the Fintek F81216A | ||
307 | LPC to 4 UART. This device has some RS485 functionality not available | ||
308 | through the PNP driver. If unsure, say N. | ||
309 | |||
310 | config SERIAL_8250_MT6577 | ||
311 | bool "Mediatek serial port support" | ||
312 | depends on SERIAL_8250 && ARCH_MEDIATEK | ||
313 | help | ||
314 | If you have a Mediatek based board and want to use the | ||
315 | serial port, say Y to this option. If unsure, say N. | ||
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 36d68d054307..5256b894e46a 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile | |||
@@ -20,3 +20,5 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o | |||
20 | obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o | 20 | obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o |
21 | obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o | 21 | obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o |
22 | obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o | 22 | obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o |
23 | obj-$(CONFIG_SERIAL_8250_FINTEK) += 8250_fintek.o | ||
24 | obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o | ||
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 26cec64dadd7..649b784081c7 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -200,10 +200,29 @@ config SERIAL_KS8695_CONSOLE | |||
200 | receives all kernel messages and warnings and which allows | 200 | receives all kernel messages and warnings and which allows |
201 | logins in single user mode). | 201 | logins in single user mode). |
202 | 202 | ||
203 | config SERIAL_MESON | ||
204 | tristate "Meson serial port support" | ||
205 | depends on ARCH_MESON | ||
206 | select SERIAL_CORE | ||
207 | help | ||
208 | This enables the driver for the on-chip UARTs of the Amlogic | ||
209 | MesonX processors. | ||
210 | |||
211 | config SERIAL_MESON_CONSOLE | ||
212 | bool "Support for console on meson" | ||
213 | depends on SERIAL_MESON=y | ||
214 | select SERIAL_CORE_CONSOLE | ||
215 | help | ||
216 | Say Y here if you wish to use a Amlogic MesonX UART as the | ||
217 | system console (the system console is the device which | ||
218 | receives all kernel messages and warnings and which allows | ||
219 | logins in single user mode) as /dev/ttyAMLx. | ||
220 | |||
203 | config SERIAL_CLPS711X | 221 | config SERIAL_CLPS711X |
204 | tristate "CLPS711X serial port support" | 222 | tristate "CLPS711X serial port support" |
205 | depends on ARCH_CLPS711X || COMPILE_TEST | 223 | depends on ARCH_CLPS711X || COMPILE_TEST |
206 | select SERIAL_CORE | 224 | select SERIAL_CORE |
225 | select SERIAL_MCTRL_GPIO if GPIOLIB | ||
207 | help | 226 | help |
208 | This enables the driver for the on-chip UARTs of the Cirrus | 227 | This enables the driver for the on-chip UARTs of the Cirrus |
209 | Logic EP711x/EP721x/EP731x processors. | 228 | Logic EP711x/EP721x/EP731x processors. |
@@ -220,7 +239,7 @@ config SERIAL_CLPS711X_CONSOLE | |||
220 | 239 | ||
221 | config SERIAL_SAMSUNG | 240 | config SERIAL_SAMSUNG |
222 | tristate "Samsung SoC serial support" | 241 | tristate "Samsung SoC serial support" |
223 | depends on PLAT_SAMSUNG | 242 | depends on PLAT_SAMSUNG || ARCH_EXYNOS |
224 | select SERIAL_CORE | 243 | select SERIAL_CORE |
225 | help | 244 | help |
226 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, | 245 | Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, |
@@ -1051,6 +1070,7 @@ config SERIAL_MSM_CONSOLE | |||
1051 | bool "MSM serial console support" | 1070 | bool "MSM serial console support" |
1052 | depends on SERIAL_MSM=y | 1071 | depends on SERIAL_MSM=y |
1053 | select SERIAL_CORE_CONSOLE | 1072 | select SERIAL_CORE_CONSOLE |
1073 | select SERIAL_EARLYCON | ||
1054 | 1074 | ||
1055 | config SERIAL_MSM_HS | 1075 | config SERIAL_MSM_HS |
1056 | tristate "MSM UART High Speed: Serial Driver" | 1076 | tristate "MSM UART High Speed: Serial Driver" |
@@ -1410,6 +1430,7 @@ config SERIAL_XILINX_PS_UART_CONSOLE | |||
1410 | bool "Cadence UART console support" | 1430 | bool "Cadence UART console support" |
1411 | depends on SERIAL_XILINX_PS_UART=y | 1431 | depends on SERIAL_XILINX_PS_UART=y |
1412 | select SERIAL_CORE_CONSOLE | 1432 | select SERIAL_CORE_CONSOLE |
1433 | select SERIAL_EARLYCON | ||
1413 | help | 1434 | help |
1414 | Enable a Cadence UART port to be the system console. | 1435 | Enable a Cadence UART port to be the system console. |
1415 | 1436 | ||
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 0080cc362e09..9a548acf5fdc 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -48,6 +48,7 @@ obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o | |||
48 | obj-$(CONFIG_SERIAL_ICOM) += icom.o | 48 | obj-$(CONFIG_SERIAL_ICOM) += icom.o |
49 | obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o | 49 | obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o |
50 | obj-$(CONFIG_SERIAL_MPSC) += mpsc.o | 50 | obj-$(CONFIG_SERIAL_MPSC) += mpsc.o |
51 | obj-$(CONFIG_SERIAL_MESON) += meson_uart.o | ||
51 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o | 52 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o |
52 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o | 53 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o |
53 | obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o | 54 | obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o |
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index d22e3d98ae23..932e01995c0a 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c | |||
@@ -462,7 +462,7 @@ static int altera_jtaguart_remove(struct platform_device *pdev) | |||
462 | } | 462 | } |
463 | 463 | ||
464 | #ifdef CONFIG_OF | 464 | #ifdef CONFIG_OF |
465 | static struct of_device_id altera_jtaguart_match[] = { | 465 | static const struct of_device_id altera_jtaguart_match[] = { |
466 | { .compatible = "ALTR,juart-1.0", }, | 466 | { .compatible = "ALTR,juart-1.0", }, |
467 | { .compatible = "altr,juart-1.0", }, | 467 | { .compatible = "altr,juart-1.0", }, |
468 | {}, | 468 | {}, |
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 6a243239dbef..1cb2cdb1bc42 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -610,7 +610,7 @@ static int altera_uart_remove(struct platform_device *pdev) | |||
610 | } | 610 | } |
611 | 611 | ||
612 | #ifdef CONFIG_OF | 612 | #ifdef CONFIG_OF |
613 | static struct of_device_id altera_uart_match[] = { | 613 | static const struct of_device_id altera_uart_match[] = { |
614 | { .compatible = "ALTR,uart-1.0", }, | 614 | { .compatible = "ALTR,uart-1.0", }, |
615 | { .compatible = "altr,uart-1.0", }, | 615 | { .compatible = "altr,uart-1.0", }, |
616 | {}, | 616 | {}, |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8572f2a57fc8..02016fcd91b8 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -678,7 +678,8 @@ static void pl011_dma_flush_buffer(struct uart_port *port) | |||
678 | __releases(&uap->port.lock) | 678 | __releases(&uap->port.lock) |
679 | __acquires(&uap->port.lock) | 679 | __acquires(&uap->port.lock) |
680 | { | 680 | { |
681 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 681 | struct uart_amba_port *uap = |
682 | container_of(port, struct uart_amba_port, port); | ||
682 | 683 | ||
683 | if (!uap->using_tx_dma) | 684 | if (!uap->using_tx_dma) |
684 | return; | 685 | return; |
@@ -1163,7 +1164,8 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap) | |||
1163 | 1164 | ||
1164 | static void pl011_stop_tx(struct uart_port *port) | 1165 | static void pl011_stop_tx(struct uart_port *port) |
1165 | { | 1166 | { |
1166 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1167 | struct uart_amba_port *uap = |
1168 | container_of(port, struct uart_amba_port, port); | ||
1167 | 1169 | ||
1168 | uap->im &= ~UART011_TXIM; | 1170 | uap->im &= ~UART011_TXIM; |
1169 | writew(uap->im, uap->port.membase + UART011_IMSC); | 1171 | writew(uap->im, uap->port.membase + UART011_IMSC); |
@@ -1172,7 +1174,8 @@ static void pl011_stop_tx(struct uart_port *port) | |||
1172 | 1174 | ||
1173 | static void pl011_start_tx(struct uart_port *port) | 1175 | static void pl011_start_tx(struct uart_port *port) |
1174 | { | 1176 | { |
1175 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1177 | struct uart_amba_port *uap = |
1178 | container_of(port, struct uart_amba_port, port); | ||
1176 | 1179 | ||
1177 | if (!pl011_dma_tx_start(uap)) { | 1180 | if (!pl011_dma_tx_start(uap)) { |
1178 | uap->im |= UART011_TXIM; | 1181 | uap->im |= UART011_TXIM; |
@@ -1182,7 +1185,8 @@ static void pl011_start_tx(struct uart_port *port) | |||
1182 | 1185 | ||
1183 | static void pl011_stop_rx(struct uart_port *port) | 1186 | static void pl011_stop_rx(struct uart_port *port) |
1184 | { | 1187 | { |
1185 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1188 | struct uart_amba_port *uap = |
1189 | container_of(port, struct uart_amba_port, port); | ||
1186 | 1190 | ||
1187 | uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM| | 1191 | uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM| |
1188 | UART011_PEIM|UART011_BEIM|UART011_OEIM); | 1192 | UART011_PEIM|UART011_BEIM|UART011_OEIM); |
@@ -1193,7 +1197,8 @@ static void pl011_stop_rx(struct uart_port *port) | |||
1193 | 1197 | ||
1194 | static void pl011_enable_ms(struct uart_port *port) | 1198 | static void pl011_enable_ms(struct uart_port *port) |
1195 | { | 1199 | { |
1196 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1200 | struct uart_amba_port *uap = |
1201 | container_of(port, struct uart_amba_port, port); | ||
1197 | 1202 | ||
1198 | uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM; | 1203 | uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM; |
1199 | writew(uap->im, uap->port.membase + UART011_IMSC); | 1204 | writew(uap->im, uap->port.membase + UART011_IMSC); |
@@ -1349,14 +1354,16 @@ static irqreturn_t pl011_int(int irq, void *dev_id) | |||
1349 | 1354 | ||
1350 | static unsigned int pl011_tx_empty(struct uart_port *port) | 1355 | static unsigned int pl011_tx_empty(struct uart_port *port) |
1351 | { | 1356 | { |
1352 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1357 | struct uart_amba_port *uap = |
1358 | container_of(port, struct uart_amba_port, port); | ||
1353 | unsigned int status = readw(uap->port.membase + UART01x_FR); | 1359 | unsigned int status = readw(uap->port.membase + UART01x_FR); |
1354 | return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; | 1360 | return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; |
1355 | } | 1361 | } |
1356 | 1362 | ||
1357 | static unsigned int pl011_get_mctrl(struct uart_port *port) | 1363 | static unsigned int pl011_get_mctrl(struct uart_port *port) |
1358 | { | 1364 | { |
1359 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1365 | struct uart_amba_port *uap = |
1366 | container_of(port, struct uart_amba_port, port); | ||
1360 | unsigned int result = 0; | 1367 | unsigned int result = 0; |
1361 | unsigned int status = readw(uap->port.membase + UART01x_FR); | 1368 | unsigned int status = readw(uap->port.membase + UART01x_FR); |
1362 | 1369 | ||
@@ -1374,7 +1381,8 @@ static unsigned int pl011_get_mctrl(struct uart_port *port) | |||
1374 | 1381 | ||
1375 | static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) | 1382 | static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) |
1376 | { | 1383 | { |
1377 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1384 | struct uart_amba_port *uap = |
1385 | container_of(port, struct uart_amba_port, port); | ||
1378 | unsigned int cr; | 1386 | unsigned int cr; |
1379 | 1387 | ||
1380 | cr = readw(uap->port.membase + UART011_CR); | 1388 | cr = readw(uap->port.membase + UART011_CR); |
@@ -1402,7 +1410,8 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
1402 | 1410 | ||
1403 | static void pl011_break_ctl(struct uart_port *port, int break_state) | 1411 | static void pl011_break_ctl(struct uart_port *port, int break_state) |
1404 | { | 1412 | { |
1405 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1413 | struct uart_amba_port *uap = |
1414 | container_of(port, struct uart_amba_port, port); | ||
1406 | unsigned long flags; | 1415 | unsigned long flags; |
1407 | unsigned int lcr_h; | 1416 | unsigned int lcr_h; |
1408 | 1417 | ||
@@ -1420,7 +1429,8 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) | |||
1420 | 1429 | ||
1421 | static void pl011_quiesce_irqs(struct uart_port *port) | 1430 | static void pl011_quiesce_irqs(struct uart_port *port) |
1422 | { | 1431 | { |
1423 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1432 | struct uart_amba_port *uap = |
1433 | container_of(port, struct uart_amba_port, port); | ||
1424 | unsigned char __iomem *regs = uap->port.membase; | 1434 | unsigned char __iomem *regs = uap->port.membase; |
1425 | 1435 | ||
1426 | writew(readw(regs + UART011_MIS), regs + UART011_ICR); | 1436 | writew(readw(regs + UART011_MIS), regs + UART011_ICR); |
@@ -1442,7 +1452,8 @@ static void pl011_quiesce_irqs(struct uart_port *port) | |||
1442 | 1452 | ||
1443 | static int pl011_get_poll_char(struct uart_port *port) | 1453 | static int pl011_get_poll_char(struct uart_port *port) |
1444 | { | 1454 | { |
1445 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1455 | struct uart_amba_port *uap = |
1456 | container_of(port, struct uart_amba_port, port); | ||
1446 | unsigned int status; | 1457 | unsigned int status; |
1447 | 1458 | ||
1448 | /* | 1459 | /* |
@@ -1461,7 +1472,8 @@ static int pl011_get_poll_char(struct uart_port *port) | |||
1461 | static void pl011_put_poll_char(struct uart_port *port, | 1472 | static void pl011_put_poll_char(struct uart_port *port, |
1462 | unsigned char ch) | 1473 | unsigned char ch) |
1463 | { | 1474 | { |
1464 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1475 | struct uart_amba_port *uap = |
1476 | container_of(port, struct uart_amba_port, port); | ||
1465 | 1477 | ||
1466 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) | 1478 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) |
1467 | barrier(); | 1479 | barrier(); |
@@ -1473,7 +1485,8 @@ static void pl011_put_poll_char(struct uart_port *port, | |||
1473 | 1485 | ||
1474 | static int pl011_hwinit(struct uart_port *port) | 1486 | static int pl011_hwinit(struct uart_port *port) |
1475 | { | 1487 | { |
1476 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1488 | struct uart_amba_port *uap = |
1489 | container_of(port, struct uart_amba_port, port); | ||
1477 | int retval; | 1490 | int retval; |
1478 | 1491 | ||
1479 | /* Optionaly enable pins to be muxed in and configured */ | 1492 | /* Optionaly enable pins to be muxed in and configured */ |
@@ -1526,7 +1539,8 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) | |||
1526 | 1539 | ||
1527 | static int pl011_startup(struct uart_port *port) | 1540 | static int pl011_startup(struct uart_port *port) |
1528 | { | 1541 | { |
1529 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1542 | struct uart_amba_port *uap = |
1543 | container_of(port, struct uart_amba_port, port); | ||
1530 | unsigned int cr, lcr_h, fbrd, ibrd; | 1544 | unsigned int cr, lcr_h, fbrd, ibrd; |
1531 | int retval; | 1545 | int retval; |
1532 | 1546 | ||
@@ -1618,7 +1632,8 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap, | |||
1618 | 1632 | ||
1619 | static void pl011_shutdown(struct uart_port *port) | 1633 | static void pl011_shutdown(struct uart_port *port) |
1620 | { | 1634 | { |
1621 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1635 | struct uart_amba_port *uap = |
1636 | container_of(port, struct uart_amba_port, port); | ||
1622 | unsigned int cr; | 1637 | unsigned int cr; |
1623 | 1638 | ||
1624 | /* | 1639 | /* |
@@ -1680,7 +1695,8 @@ static void | |||
1680 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, | 1695 | pl011_set_termios(struct uart_port *port, struct ktermios *termios, |
1681 | struct ktermios *old) | 1696 | struct ktermios *old) |
1682 | { | 1697 | { |
1683 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1698 | struct uart_amba_port *uap = |
1699 | container_of(port, struct uart_amba_port, port); | ||
1684 | unsigned int lcr_h, old_cr; | 1700 | unsigned int lcr_h, old_cr; |
1685 | unsigned long flags; | 1701 | unsigned long flags; |
1686 | unsigned int baud, quot, clkdiv; | 1702 | unsigned int baud, quot, clkdiv; |
@@ -1822,7 +1838,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1822 | 1838 | ||
1823 | static const char *pl011_type(struct uart_port *port) | 1839 | static const char *pl011_type(struct uart_port *port) |
1824 | { | 1840 | { |
1825 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1841 | struct uart_amba_port *uap = |
1842 | container_of(port, struct uart_amba_port, port); | ||
1826 | return uap->port.type == PORT_AMBA ? uap->type : NULL; | 1843 | return uap->port.type == PORT_AMBA ? uap->type : NULL; |
1827 | } | 1844 | } |
1828 | 1845 | ||
@@ -1900,7 +1917,8 @@ static struct uart_amba_port *amba_ports[UART_NR]; | |||
1900 | 1917 | ||
1901 | static void pl011_console_putchar(struct uart_port *port, int ch) | 1918 | static void pl011_console_putchar(struct uart_port *port, int ch) |
1902 | { | 1919 | { |
1903 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1920 | struct uart_amba_port *uap = |
1921 | container_of(port, struct uart_amba_port, port); | ||
1904 | 1922 | ||
1905 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) | 1923 | while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) |
1906 | barrier(); | 1924 | barrier(); |
diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index 7810aa290edf..d62d8daac8ab 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/tty.h> | 33 | #include <linux/tty.h> |
34 | #include <linux/tty_flip.h> | 34 | #include <linux/tty_flip.h> |
35 | #include <linux/serial_core.h> | 35 | #include <linux/serial_core.h> |
36 | #include <linux/gpio.h> | ||
36 | 37 | ||
37 | #include <asm/bfin_sport.h> | 38 | #include <asm/bfin_sport.h> |
38 | #include <asm/delay.h> | 39 | #include <asm/delay.h> |
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index dec0fd725d80..7da9911e95f0 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -108,22 +108,23 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
108 | static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) | 108 | static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id) |
109 | { | 109 | { |
110 | struct bfin_serial_port *uart = dev_id; | 110 | struct bfin_serial_port *uart = dev_id; |
111 | unsigned int status = bfin_serial_get_mctrl(&uart->port); | 111 | struct uart_port *uport = &uart->port; |
112 | unsigned int status = bfin_serial_get_mctrl(uport); | ||
112 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS | 113 | #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS |
113 | struct tty_struct *tty = uart->port.state->port.tty; | ||
114 | 114 | ||
115 | UART_CLEAR_SCTS(uart); | 115 | UART_CLEAR_SCTS(uart); |
116 | if (tty->hw_stopped) { | 116 | if (uport->hw_stopped) { |
117 | if (status) { | 117 | if (status) { |
118 | tty->hw_stopped = 0; | 118 | uport->hw_stopped = 0; |
119 | uart_write_wakeup(&uart->port); | 119 | uart_write_wakeup(uport); |
120 | } | 120 | } |
121 | } else { | 121 | } else { |
122 | if (!status) | 122 | if (!status) |
123 | tty->hw_stopped = 1; | 123 | uport->hw_stopped = 1; |
124 | } | 124 | } |
125 | #else | ||
126 | uart_handle_cts_change(uport, status & TIOCM_CTS); | ||
125 | #endif | 127 | #endif |
126 | uart_handle_cts_change(&uart->port, status & TIOCM_CTS); | ||
127 | 128 | ||
128 | return IRQ_HANDLED; | 129 | return IRQ_HANDLED; |
129 | } | 130 | } |
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index f5b4c3d7e38f..acfe31773643 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/mfd/syscon.h> | 33 | #include <linux/mfd/syscon.h> |
34 | #include <linux/mfd/syscon/clps711x.h> | 34 | #include <linux/mfd/syscon/clps711x.h> |
35 | 35 | ||
36 | #include "serial_mctrl_gpio.h" | ||
37 | |||
36 | #define UART_CLPS711X_DEVNAME "ttyCL" | 38 | #define UART_CLPS711X_DEVNAME "ttyCL" |
37 | #define UART_CLPS711X_NR 2 | 39 | #define UART_CLPS711X_NR 2 |
38 | #define UART_CLPS711X_MAJOR 204 | 40 | #define UART_CLPS711X_MAJOR 204 |
@@ -62,7 +64,7 @@ struct clps711x_port { | |||
62 | unsigned int tx_enabled; | 64 | unsigned int tx_enabled; |
63 | int rx_irq; | 65 | int rx_irq; |
64 | struct regmap *syscon; | 66 | struct regmap *syscon; |
65 | bool use_ms; | 67 | struct mctrl_gpios *gpios; |
66 | }; | 68 | }; |
67 | 69 | ||
68 | static struct uart_driver clps711x_uart = { | 70 | static struct uart_driver clps711x_uart = { |
@@ -198,28 +200,17 @@ static unsigned int uart_clps711x_tx_empty(struct uart_port *port) | |||
198 | 200 | ||
199 | static unsigned int uart_clps711x_get_mctrl(struct uart_port *port) | 201 | static unsigned int uart_clps711x_get_mctrl(struct uart_port *port) |
200 | { | 202 | { |
203 | unsigned int result = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | ||
201 | struct clps711x_port *s = dev_get_drvdata(port->dev); | 204 | struct clps711x_port *s = dev_get_drvdata(port->dev); |
202 | unsigned int result = 0; | ||
203 | |||
204 | if (s->use_ms) { | ||
205 | u32 sysflg = 0; | ||
206 | |||
207 | regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); | ||
208 | if (sysflg & SYSFLG1_DCD) | ||
209 | result |= TIOCM_CAR; | ||
210 | if (sysflg & SYSFLG1_DSR) | ||
211 | result |= TIOCM_DSR; | ||
212 | if (sysflg & SYSFLG1_CTS) | ||
213 | result |= TIOCM_CTS; | ||
214 | } else | ||
215 | result = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | ||
216 | 205 | ||
217 | return result; | 206 | return mctrl_gpio_get(s->gpios, &result); |
218 | } | 207 | } |
219 | 208 | ||
220 | static void uart_clps711x_set_mctrl(struct uart_port *port, unsigned int mctrl) | 209 | static void uart_clps711x_set_mctrl(struct uart_port *port, unsigned int mctrl) |
221 | { | 210 | { |
222 | /* Do nothing */ | 211 | struct clps711x_port *s = dev_get_drvdata(port->dev); |
212 | |||
213 | mctrl_gpio_set(s->gpios, mctrl); | ||
223 | } | 214 | } |
224 | 215 | ||
225 | static void uart_clps711x_break_ctl(struct uart_port *port, int break_state) | 216 | static void uart_clps711x_break_ctl(struct uart_port *port, int break_state) |
@@ -490,15 +481,10 @@ static int uart_clps711x_probe(struct platform_device *pdev) | |||
490 | s->syscon = syscon_regmap_lookup_by_pdevname(syscon_name); | 481 | s->syscon = syscon_regmap_lookup_by_pdevname(syscon_name); |
491 | if (IS_ERR(s->syscon)) | 482 | if (IS_ERR(s->syscon)) |
492 | return PTR_ERR(s->syscon); | 483 | return PTR_ERR(s->syscon); |
493 | |||
494 | s->use_ms = !index; | ||
495 | } else { | 484 | } else { |
496 | s->syscon = syscon_regmap_lookup_by_phandle(np, "syscon"); | 485 | s->syscon = syscon_regmap_lookup_by_phandle(np, "syscon"); |
497 | if (IS_ERR(s->syscon)) | 486 | if (IS_ERR(s->syscon)) |
498 | return PTR_ERR(s->syscon); | 487 | return PTR_ERR(s->syscon); |
499 | |||
500 | if (!index) | ||
501 | s->use_ms = of_property_read_bool(np, "uart-use-ms"); | ||
502 | } | 488 | } |
503 | 489 | ||
504 | s->port.line = index; | 490 | s->port.line = index; |
@@ -513,6 +499,8 @@ static int uart_clps711x_probe(struct platform_device *pdev) | |||
513 | 499 | ||
514 | platform_set_drvdata(pdev, s); | 500 | platform_set_drvdata(pdev, s); |
515 | 501 | ||
502 | s->gpios = mctrl_gpio_init(&pdev->dev, 0); | ||
503 | |||
516 | ret = uart_add_one_port(&clps711x_uart, &s->port); | 504 | ret = uart_add_one_port(&clps711x_uart, &s->port); |
517 | if (ret) | 505 | if (ret) |
518 | return ret; | 506 | return ret; |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 044e86d528ae..8f62a3cec23e 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -80,6 +80,7 @@ | |||
80 | #define URXD_FRMERR (1<<12) | 80 | #define URXD_FRMERR (1<<12) |
81 | #define URXD_BRK (1<<11) | 81 | #define URXD_BRK (1<<11) |
82 | #define URXD_PRERR (1<<10) | 82 | #define URXD_PRERR (1<<10) |
83 | #define URXD_RX_DATA (0xFF<<0) | ||
83 | #define UCR1_ADEN (1<<15) /* Auto detect interrupt */ | 84 | #define UCR1_ADEN (1<<15) /* Auto detect interrupt */ |
84 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ | 85 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ |
85 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ | 86 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ |
@@ -435,12 +436,14 @@ static void imx_stop_rx(struct uart_port *port) | |||
435 | struct imx_port *sport = (struct imx_port *)port; | 436 | struct imx_port *sport = (struct imx_port *)port; |
436 | unsigned long temp; | 437 | unsigned long temp; |
437 | 438 | ||
438 | /* | 439 | if (sport->dma_is_enabled && sport->dma_is_rxing) { |
439 | * We are maybe in the SMP context, so if the DMA TX thread is running | 440 | if (sport->port.suspended) { |
440 | * on other cpu, we have to wait for it to finish. | 441 | dmaengine_terminate_all(sport->dma_chan_rx); |
441 | */ | 442 | sport->dma_is_rxing = 0; |
442 | if (sport->dma_is_enabled && sport->dma_is_rxing) | 443 | } else { |
443 | return; | 444 | return; |
445 | } | ||
446 | } | ||
444 | 447 | ||
445 | temp = readl(sport->port.membase + UCR2); | 448 | temp = readl(sport->port.membase + UCR2); |
446 | writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2); | 449 | writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2); |
@@ -464,9 +467,19 @@ static inline void imx_transmit_buffer(struct imx_port *sport) | |||
464 | { | 467 | { |
465 | struct circ_buf *xmit = &sport->port.state->xmit; | 468 | struct circ_buf *xmit = &sport->port.state->xmit; |
466 | 469 | ||
470 | if (sport->port.x_char) { | ||
471 | /* Send next char */ | ||
472 | writel(sport->port.x_char, sport->port.membase + URTX0); | ||
473 | return; | ||
474 | } | ||
475 | |||
476 | if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { | ||
477 | imx_stop_tx(&sport->port); | ||
478 | return; | ||
479 | } | ||
480 | |||
467 | while (!uart_circ_empty(xmit) && | 481 | while (!uart_circ_empty(xmit) && |
468 | !(readl(sport->port.membase + uts_reg(sport)) | 482 | !(readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)) { |
469 | & UTS_TXFULL)) { | ||
470 | /* send xmit->buf[xmit->tail] | 483 | /* send xmit->buf[xmit->tail] |
471 | * out the port here */ | 484 | * out the port here */ |
472 | writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); | 485 | writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); |
@@ -567,9 +580,6 @@ static void imx_start_tx(struct uart_port *port) | |||
567 | struct imx_port *sport = (struct imx_port *)port; | 580 | struct imx_port *sport = (struct imx_port *)port; |
568 | unsigned long temp; | 581 | unsigned long temp; |
569 | 582 | ||
570 | if (uart_circ_empty(&port->state->xmit)) | ||
571 | return; | ||
572 | |||
573 | if (USE_IRDA(sport)) { | 583 | if (USE_IRDA(sport)) { |
574 | /* half duplex in IrDA mode; have to disable receive mode */ | 584 | /* half duplex in IrDA mode; have to disable receive mode */ |
575 | temp = readl(sport->port.membase + UCR4); | 585 | temp = readl(sport->port.membase + UCR4); |
@@ -604,7 +614,10 @@ static void imx_start_tx(struct uart_port *port) | |||
604 | } | 614 | } |
605 | 615 | ||
606 | if (sport->dma_is_enabled) { | 616 | if (sport->dma_is_enabled) { |
607 | imx_dma_tx(sport); | 617 | /* FIXME: port->x_char must be transmitted if != 0 */ |
618 | if (!uart_circ_empty(&port->state->xmit) && | ||
619 | !uart_tx_stopped(port)) | ||
620 | imx_dma_tx(sport); | ||
608 | return; | 621 | return; |
609 | } | 622 | } |
610 | 623 | ||
@@ -632,27 +645,10 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id) | |||
632 | static irqreturn_t imx_txint(int irq, void *dev_id) | 645 | static irqreturn_t imx_txint(int irq, void *dev_id) |
633 | { | 646 | { |
634 | struct imx_port *sport = dev_id; | 647 | struct imx_port *sport = dev_id; |
635 | struct circ_buf *xmit = &sport->port.state->xmit; | ||
636 | unsigned long flags; | 648 | unsigned long flags; |
637 | 649 | ||
638 | spin_lock_irqsave(&sport->port.lock, flags); | 650 | spin_lock_irqsave(&sport->port.lock, flags); |
639 | if (sport->port.x_char) { | ||
640 | /* Send next char */ | ||
641 | writel(sport->port.x_char, sport->port.membase + URTX0); | ||
642 | goto out; | ||
643 | } | ||
644 | |||
645 | if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { | ||
646 | imx_stop_tx(&sport->port); | ||
647 | goto out; | ||
648 | } | ||
649 | |||
650 | imx_transmit_buffer(sport); | 651 | imx_transmit_buffer(sport); |
651 | |||
652 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
653 | uart_write_wakeup(&sport->port); | ||
654 | |||
655 | out: | ||
656 | spin_unlock_irqrestore(&sport->port.lock, flags); | 652 | spin_unlock_irqrestore(&sport->port.lock, flags); |
657 | return IRQ_HANDLED; | 653 | return IRQ_HANDLED; |
658 | } | 654 | } |
@@ -823,11 +819,9 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
823 | struct imx_port *sport = (struct imx_port *)port; | 819 | struct imx_port *sport = (struct imx_port *)port; |
824 | unsigned long temp; | 820 | unsigned long temp; |
825 | 821 | ||
826 | temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS; | 822 | temp = readl(sport->port.membase + UCR2) & ~(UCR2_CTS | UCR2_CTSC); |
827 | |||
828 | if (mctrl & TIOCM_RTS) | 823 | if (mctrl & TIOCM_RTS) |
829 | if (!sport->dma_is_enabled) | 824 | temp |= UCR2_CTS | UCR2_CTSC; |
830 | temp |= UCR2_CTS; | ||
831 | 825 | ||
832 | writel(temp, sport->port.membase + UCR2); | 826 | writel(temp, sport->port.membase + UCR2); |
833 | 827 | ||
@@ -1225,9 +1219,18 @@ static void imx_shutdown(struct uart_port *port) | |||
1225 | unsigned long flags; | 1219 | unsigned long flags; |
1226 | 1220 | ||
1227 | if (sport->dma_is_enabled) { | 1221 | if (sport->dma_is_enabled) { |
1222 | int ret; | ||
1223 | |||
1228 | /* We have to wait for the DMA to finish. */ | 1224 | /* We have to wait for the DMA to finish. */ |
1229 | wait_event(sport->dma_wait, | 1225 | ret = wait_event_interruptible(sport->dma_wait, |
1230 | !sport->dma_is_rxing && !sport->dma_is_txing); | 1226 | !sport->dma_is_rxing && !sport->dma_is_txing); |
1227 | if (ret != 0) { | ||
1228 | sport->dma_is_rxing = 0; | ||
1229 | sport->dma_is_txing = 0; | ||
1230 | dmaengine_terminate_all(sport->dma_chan_tx); | ||
1231 | dmaengine_terminate_all(sport->dma_chan_rx); | ||
1232 | } | ||
1233 | imx_stop_tx(port); | ||
1231 | imx_stop_rx(port); | 1234 | imx_stop_rx(port); |
1232 | imx_disable_dma(sport); | 1235 | imx_disable_dma(sport); |
1233 | imx_uart_dma_exit(sport); | 1236 | imx_uart_dma_exit(sport); |
@@ -1506,32 +1509,10 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1506 | #if defined(CONFIG_CONSOLE_POLL) | 1509 | #if defined(CONFIG_CONSOLE_POLL) |
1507 | static int imx_poll_get_char(struct uart_port *port) | 1510 | static int imx_poll_get_char(struct uart_port *port) |
1508 | { | 1511 | { |
1509 | struct imx_port_ucrs old_ucr; | 1512 | if (!(readl(port->membase + USR2) & USR2_RDR)) |
1510 | unsigned int status; | 1513 | return NO_POLL_CHAR; |
1511 | unsigned char c; | ||
1512 | |||
1513 | /* save control registers */ | ||
1514 | imx_port_ucrs_save(port, &old_ucr); | ||
1515 | |||
1516 | /* disable interrupts */ | ||
1517 | writel(UCR1_UARTEN, port->membase + UCR1); | ||
1518 | writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI), | ||
1519 | port->membase + UCR2); | ||
1520 | writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN), | ||
1521 | port->membase + UCR3); | ||
1522 | |||
1523 | /* poll */ | ||
1524 | do { | ||
1525 | status = readl(port->membase + USR2); | ||
1526 | } while (~status & USR2_RDR); | ||
1527 | |||
1528 | /* read */ | ||
1529 | c = readl(port->membase + URXD0); | ||
1530 | |||
1531 | /* restore control registers */ | ||
1532 | imx_port_ucrs_restore(port, &old_ucr); | ||
1533 | 1514 | ||
1534 | return c; | 1515 | return readl(port->membase + URXD0) & URXD_RX_DATA; |
1535 | } | 1516 | } |
1536 | 1517 | ||
1537 | static void imx_poll_put_char(struct uart_port *port, unsigned char c) | 1518 | static void imx_poll_put_char(struct uart_port *port, unsigned char c) |
diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 844d5e4eb1aa..af7013488aeb 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h | |||
@@ -67,6 +67,16 @@ do { \ | |||
67 | #define MAXPORTS 8 | 67 | #define MAXPORTS 8 |
68 | #define MAX_STOPS_SENT 5 | 68 | #define MAX_STOPS_SENT 5 |
69 | 69 | ||
70 | /* Board ids */ | ||
71 | #define PCI_DEVICE_ID_NEO_4 0x00B0 | ||
72 | #define PCI_DEVICE_ID_NEO_1_422 0x00CC | ||
73 | #define PCI_DEVICE_ID_NEO_1_422_485 0x00CD | ||
74 | #define PCI_DEVICE_ID_NEO_2_422_485 0x00CE | ||
75 | #define PCIE_DEVICE_ID_NEO_8 0x00F0 | ||
76 | #define PCIE_DEVICE_ID_NEO_4 0x00F1 | ||
77 | #define PCIE_DEVICE_ID_NEO_4RJ45 0x00F2 | ||
78 | #define PCIE_DEVICE_ID_NEO_8RJ45 0x00F3 | ||
79 | |||
70 | /* Board type definitions */ | 80 | /* Board type definitions */ |
71 | 81 | ||
72 | #define T_NEO 0000 | 82 | #define T_NEO 0000 |
diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index a47d882d6743..d2885a7bb090 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c | |||
@@ -93,12 +93,34 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
93 | /* store the info for the board we've found */ | 93 | /* store the info for the board we've found */ |
94 | brd->boardnum = adapter_count++; | 94 | brd->boardnum = adapter_count++; |
95 | brd->pci_dev = pdev; | 95 | brd->pci_dev = pdev; |
96 | if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM) | 96 | |
97 | switch (pdev->device) { | ||
98 | |||
99 | case PCI_DEVICE_ID_NEO_2DB9: | ||
100 | case PCI_DEVICE_ID_NEO_2DB9PRI: | ||
101 | case PCI_DEVICE_ID_NEO_2RJ45: | ||
102 | case PCI_DEVICE_ID_NEO_2RJ45PRI: | ||
103 | case PCI_DEVICE_ID_NEO_2_422_485: | ||
104 | brd->maxports = 2; | ||
105 | break; | ||
106 | |||
107 | case PCI_DEVICE_ID_NEO_4: | ||
108 | case PCIE_DEVICE_ID_NEO_4: | ||
109 | case PCIE_DEVICE_ID_NEO_4RJ45: | ||
110 | case PCIE_DEVICE_ID_NEO_4_IBM: | ||
97 | brd->maxports = 4; | 111 | brd->maxports = 4; |
98 | else if (pdev->device == PCI_DEVICE_ID_DIGI_NEO_8) | 112 | break; |
113 | |||
114 | case PCI_DEVICE_ID_DIGI_NEO_8: | ||
115 | case PCIE_DEVICE_ID_NEO_8: | ||
116 | case PCIE_DEVICE_ID_NEO_8RJ45: | ||
99 | brd->maxports = 8; | 117 | brd->maxports = 8; |
100 | else | 118 | break; |
101 | brd->maxports = 2; | 119 | |
120 | default: | ||
121 | brd->maxports = 1; | ||
122 | break; | ||
123 | } | ||
102 | 124 | ||
103 | spin_lock_init(&brd->bd_intr_lock); | 125 | spin_lock_init(&brd->bd_intr_lock); |
104 | 126 | ||
@@ -209,6 +231,14 @@ static struct pci_device_id jsm_pci_tbl[] = { | |||
209 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 }, | 231 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 }, |
210 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 }, | 232 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 }, |
211 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_NEO_8), 0, 0, 5 }, | 233 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_NEO_8), 0, 0, 5 }, |
234 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_4), 0, 0, 6 }, | ||
235 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_1_422), 0, 0, 7 }, | ||
236 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_1_422_485), 0, 0, 8 }, | ||
237 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2_422_485), 0, 0, 9 }, | ||
238 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_8), 0, 0, 10 }, | ||
239 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4), 0, 0, 11 }, | ||
240 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4RJ45), 0, 0, 12 }, | ||
241 | { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_8RJ45), 0, 0, 13 }, | ||
212 | { 0, } | 242 | { 0, } |
213 | }; | 243 | }; |
214 | MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); | 244 | MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); |
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 6ec7501b464d..129dc5be6028 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c | |||
@@ -46,6 +46,8 @@ static atomic_t kgdb_nmi_num_readers = ATOMIC_INIT(0); | |||
46 | 46 | ||
47 | static int kgdb_nmi_console_setup(struct console *co, char *options) | 47 | static int kgdb_nmi_console_setup(struct console *co, char *options) |
48 | { | 48 | { |
49 | arch_kgdb_ops.enable_nmi(1); | ||
50 | |||
49 | /* The NMI console uses the dbg_io_ops to issue console messages. To | 51 | /* The NMI console uses the dbg_io_ops to issue console messages. To |
50 | * avoid duplicate messages during kdb sessions we must inform kdb's | 52 | * avoid duplicate messages during kdb sessions we must inform kdb's |
51 | * I/O utilities that messages sent to the console will automatically | 53 | * I/O utilities that messages sent to the console will automatically |
@@ -77,7 +79,7 @@ static struct console kgdb_nmi_console = { | |||
77 | .setup = kgdb_nmi_console_setup, | 79 | .setup = kgdb_nmi_console_setup, |
78 | .write = kgdb_nmi_console_write, | 80 | .write = kgdb_nmi_console_write, |
79 | .device = kgdb_nmi_console_device, | 81 | .device = kgdb_nmi_console_device, |
80 | .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_ENABLED, | 82 | .flags = CON_PRINTBUFFER | CON_ANYTIME, |
81 | .index = -1, | 83 | .index = -1, |
82 | }; | 84 | }; |
83 | 85 | ||
@@ -354,7 +356,6 @@ int kgdb_register_nmi_console(void) | |||
354 | } | 356 | } |
355 | 357 | ||
356 | register_console(&kgdb_nmi_console); | 358 | register_console(&kgdb_nmi_console); |
357 | arch_kgdb_ops.enable_nmi(1); | ||
358 | 359 | ||
359 | return 0; | 360 | return 0; |
360 | err_drv_reg: | 361 | err_drv_reg: |
diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c new file mode 100644 index 000000000000..15c749753317 --- /dev/null +++ b/drivers/tty/serial/meson_uart.c | |||
@@ -0,0 +1,634 @@ | |||
1 | /* | ||
2 | * Based on meson_uart.c, by AMLOGIC, INC. | ||
3 | * | ||
4 | * Copyright (C) 2014 Carlo Caione <carlo@caione.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/console.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/of.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/serial.h> | ||
27 | #include <linux/serial_core.h> | ||
28 | #include <linux/tty.h> | ||
29 | #include <linux/tty_flip.h> | ||
30 | |||
31 | /* Register offsets */ | ||
32 | #define AML_UART_WFIFO 0x00 | ||
33 | #define AML_UART_RFIFO 0x04 | ||
34 | #define AML_UART_CONTROL 0x08 | ||
35 | #define AML_UART_STATUS 0x0c | ||
36 | #define AML_UART_MISC 0x10 | ||
37 | #define AML_UART_REG5 0x14 | ||
38 | |||
39 | /* AML_UART_CONTROL bits */ | ||
40 | #define AML_UART_TX_EN BIT(12) | ||
41 | #define AML_UART_RX_EN BIT(13) | ||
42 | #define AML_UART_TX_RST BIT(22) | ||
43 | #define AML_UART_RX_RST BIT(23) | ||
44 | #define AML_UART_CLR_ERR BIT(24) | ||
45 | #define AML_UART_RX_INT_EN BIT(27) | ||
46 | #define AML_UART_TX_INT_EN BIT(28) | ||
47 | #define AML_UART_DATA_LEN_MASK (0x03 << 20) | ||
48 | #define AML_UART_DATA_LEN_8BIT (0x00 << 20) | ||
49 | #define AML_UART_DATA_LEN_7BIT (0x01 << 20) | ||
50 | #define AML_UART_DATA_LEN_6BIT (0x02 << 20) | ||
51 | #define AML_UART_DATA_LEN_5BIT (0x03 << 20) | ||
52 | |||
53 | /* AML_UART_STATUS bits */ | ||
54 | #define AML_UART_PARITY_ERR BIT(16) | ||
55 | #define AML_UART_FRAME_ERR BIT(17) | ||
56 | #define AML_UART_TX_FIFO_WERR BIT(18) | ||
57 | #define AML_UART_RX_EMPTY BIT(20) | ||
58 | #define AML_UART_TX_FULL BIT(21) | ||
59 | #define AML_UART_TX_EMPTY BIT(22) | ||
60 | #define AML_UART_ERR (AML_UART_PARITY_ERR | \ | ||
61 | AML_UART_FRAME_ERR | \ | ||
62 | AML_UART_TX_FIFO_WERR) | ||
63 | |||
64 | /* AML_UART_CONTROL bits */ | ||
65 | #define AML_UART_TWO_WIRE_EN BIT(15) | ||
66 | #define AML_UART_PARITY_TYPE BIT(18) | ||
67 | #define AML_UART_PARITY_EN BIT(19) | ||
68 | #define AML_UART_CLEAR_ERR BIT(24) | ||
69 | #define AML_UART_STOP_BIN_LEN_MASK (0x03 << 16) | ||
70 | #define AML_UART_STOP_BIN_1SB (0x00 << 16) | ||
71 | #define AML_UART_STOP_BIN_2SB (0x01 << 16) | ||
72 | |||
73 | /* AML_UART_MISC bits */ | ||
74 | #define AML_UART_XMIT_IRQ(c) (((c) & 0xff) << 8) | ||
75 | #define AML_UART_RECV_IRQ(c) ((c) & 0xff) | ||
76 | |||
77 | /* AML_UART_REG5 bits */ | ||
78 | #define AML_UART_BAUD_MASK 0x7fffff | ||
79 | #define AML_UART_BAUD_USE BIT(23) | ||
80 | |||
81 | #define AML_UART_PORT_NUM 6 | ||
82 | #define AML_UART_DEV_NAME "ttyAML" | ||
83 | |||
84 | |||
85 | static struct uart_driver meson_uart_driver; | ||
86 | |||
87 | static struct uart_port *meson_ports[AML_UART_PORT_NUM]; | ||
88 | |||
89 | static void meson_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
90 | { | ||
91 | } | ||
92 | |||
93 | static unsigned int meson_uart_get_mctrl(struct uart_port *port) | ||
94 | { | ||
95 | return TIOCM_CTS; | ||
96 | } | ||
97 | |||
98 | static unsigned int meson_uart_tx_empty(struct uart_port *port) | ||
99 | { | ||
100 | u32 val; | ||
101 | |||
102 | val = readl(port->membase + AML_UART_STATUS); | ||
103 | return (val & AML_UART_TX_EMPTY) ? TIOCSER_TEMT : 0; | ||
104 | } | ||
105 | |||
106 | static void meson_uart_stop_tx(struct uart_port *port) | ||
107 | { | ||
108 | u32 val; | ||
109 | |||
110 | val = readl(port->membase + AML_UART_CONTROL); | ||
111 | val &= ~AML_UART_TX_EN; | ||
112 | writel(val, port->membase + AML_UART_CONTROL); | ||
113 | } | ||
114 | |||
115 | static void meson_uart_stop_rx(struct uart_port *port) | ||
116 | { | ||
117 | u32 val; | ||
118 | |||
119 | val = readl(port->membase + AML_UART_CONTROL); | ||
120 | val &= ~AML_UART_RX_EN; | ||
121 | writel(val, port->membase + AML_UART_CONTROL); | ||
122 | } | ||
123 | |||
124 | static void meson_uart_shutdown(struct uart_port *port) | ||
125 | { | ||
126 | unsigned long flags; | ||
127 | u32 val; | ||
128 | |||
129 | free_irq(port->irq, port); | ||
130 | |||
131 | spin_lock_irqsave(&port->lock, flags); | ||
132 | |||
133 | val = readl(port->membase + AML_UART_CONTROL); | ||
134 | val &= ~(AML_UART_RX_EN | AML_UART_TX_EN); | ||
135 | val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN); | ||
136 | writel(val, port->membase + AML_UART_CONTROL); | ||
137 | |||
138 | spin_unlock_irqrestore(&port->lock, flags); | ||
139 | } | ||
140 | |||
141 | static void meson_uart_start_tx(struct uart_port *port) | ||
142 | { | ||
143 | struct circ_buf *xmit = &port->state->xmit; | ||
144 | unsigned int ch; | ||
145 | |||
146 | if (uart_tx_stopped(port)) { | ||
147 | meson_uart_stop_tx(port); | ||
148 | return; | ||
149 | } | ||
150 | |||
151 | while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) { | ||
152 | if (port->x_char) { | ||
153 | writel(port->x_char, port->membase + AML_UART_WFIFO); | ||
154 | port->icount.tx++; | ||
155 | port->x_char = 0; | ||
156 | continue; | ||
157 | } | ||
158 | |||
159 | if (uart_circ_empty(xmit)) | ||
160 | break; | ||
161 | |||
162 | ch = xmit->buf[xmit->tail]; | ||
163 | writel(ch, port->membase + AML_UART_WFIFO); | ||
164 | xmit->tail = (xmit->tail+1) & (SERIAL_XMIT_SIZE - 1); | ||
165 | port->icount.tx++; | ||
166 | } | ||
167 | |||
168 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
169 | uart_write_wakeup(port); | ||
170 | } | ||
171 | |||
172 | static void meson_receive_chars(struct uart_port *port) | ||
173 | { | ||
174 | struct tty_port *tport = &port->state->port; | ||
175 | char flag; | ||
176 | u32 status, ch, mode; | ||
177 | |||
178 | do { | ||
179 | flag = TTY_NORMAL; | ||
180 | port->icount.rx++; | ||
181 | status = readl(port->membase + AML_UART_STATUS); | ||
182 | |||
183 | if (status & AML_UART_ERR) { | ||
184 | if (status & AML_UART_TX_FIFO_WERR) | ||
185 | port->icount.overrun++; | ||
186 | else if (status & AML_UART_FRAME_ERR) | ||
187 | port->icount.frame++; | ||
188 | else if (status & AML_UART_PARITY_ERR) | ||
189 | port->icount.frame++; | ||
190 | |||
191 | mode = readl(port->membase + AML_UART_CONTROL); | ||
192 | mode |= AML_UART_CLEAR_ERR; | ||
193 | writel(mode, port->membase + AML_UART_CONTROL); | ||
194 | |||
195 | /* It doesn't clear to 0 automatically */ | ||
196 | mode &= ~AML_UART_CLEAR_ERR; | ||
197 | writel(mode, port->membase + AML_UART_CONTROL); | ||
198 | |||
199 | status &= port->read_status_mask; | ||
200 | if (status & AML_UART_FRAME_ERR) | ||
201 | flag = TTY_FRAME; | ||
202 | else if (status & AML_UART_PARITY_ERR) | ||
203 | flag = TTY_PARITY; | ||
204 | } | ||
205 | |||
206 | ch = readl(port->membase + AML_UART_RFIFO); | ||
207 | ch &= 0xff; | ||
208 | |||
209 | if ((status & port->ignore_status_mask) == 0) | ||
210 | tty_insert_flip_char(tport, ch, flag); | ||
211 | |||
212 | if (status & AML_UART_TX_FIFO_WERR) | ||
213 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); | ||
214 | |||
215 | } while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)); | ||
216 | |||
217 | spin_unlock(&port->lock); | ||
218 | tty_flip_buffer_push(tport); | ||
219 | spin_lock(&port->lock); | ||
220 | } | ||
221 | |||
222 | static irqreturn_t meson_uart_interrupt(int irq, void *dev_id) | ||
223 | { | ||
224 | struct uart_port *port = (struct uart_port *)dev_id; | ||
225 | |||
226 | spin_lock(&port->lock); | ||
227 | |||
228 | if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)) | ||
229 | meson_receive_chars(port); | ||
230 | |||
231 | if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) | ||
232 | meson_uart_start_tx(port); | ||
233 | |||
234 | spin_unlock(&port->lock); | ||
235 | |||
236 | return IRQ_HANDLED; | ||
237 | } | ||
238 | |||
239 | static const char *meson_uart_type(struct uart_port *port) | ||
240 | { | ||
241 | return (port->type == PORT_MESON) ? "meson_uart" : NULL; | ||
242 | } | ||
243 | |||
244 | static int meson_uart_startup(struct uart_port *port) | ||
245 | { | ||
246 | u32 val; | ||
247 | int ret = 0; | ||
248 | |||
249 | val = readl(port->membase + AML_UART_CONTROL); | ||
250 | val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR); | ||
251 | writel(val, port->membase + AML_UART_CONTROL); | ||
252 | |||
253 | val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR); | ||
254 | writel(val, port->membase + AML_UART_CONTROL); | ||
255 | |||
256 | val |= (AML_UART_RX_EN | AML_UART_TX_EN); | ||
257 | writel(val, port->membase + AML_UART_CONTROL); | ||
258 | |||
259 | val |= (AML_UART_RX_INT_EN | AML_UART_TX_INT_EN); | ||
260 | writel(val, port->membase + AML_UART_CONTROL); | ||
261 | |||
262 | val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2)); | ||
263 | writel(val, port->membase + AML_UART_MISC); | ||
264 | |||
265 | ret = request_irq(port->irq, meson_uart_interrupt, 0, | ||
266 | meson_uart_type(port), port); | ||
267 | |||
268 | return ret; | ||
269 | } | ||
270 | |||
271 | static void meson_uart_change_speed(struct uart_port *port, unsigned long baud) | ||
272 | { | ||
273 | u32 val; | ||
274 | |||
275 | while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_EMPTY)) | ||
276 | cpu_relax(); | ||
277 | |||
278 | val = readl(port->membase + AML_UART_REG5); | ||
279 | val &= ~AML_UART_BAUD_MASK; | ||
280 | val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1; | ||
281 | val |= AML_UART_BAUD_USE; | ||
282 | writel(val, port->membase + AML_UART_REG5); | ||
283 | } | ||
284 | |||
285 | static void meson_uart_set_termios(struct uart_port *port, | ||
286 | struct ktermios *termios, | ||
287 | struct ktermios *old) | ||
288 | { | ||
289 | unsigned int cflags, iflags, baud; | ||
290 | unsigned long flags; | ||
291 | u32 val; | ||
292 | |||
293 | spin_lock_irqsave(&port->lock, flags); | ||
294 | |||
295 | cflags = termios->c_cflag; | ||
296 | iflags = termios->c_iflag; | ||
297 | |||
298 | val = readl(port->membase + AML_UART_CONTROL); | ||
299 | |||
300 | val &= ~AML_UART_DATA_LEN_MASK; | ||
301 | switch (cflags & CSIZE) { | ||
302 | case CS8: | ||
303 | val |= AML_UART_DATA_LEN_8BIT; | ||
304 | break; | ||
305 | case CS7: | ||
306 | val |= AML_UART_DATA_LEN_7BIT; | ||
307 | break; | ||
308 | case CS6: | ||
309 | val |= AML_UART_DATA_LEN_6BIT; | ||
310 | break; | ||
311 | case CS5: | ||
312 | val |= AML_UART_DATA_LEN_5BIT; | ||
313 | break; | ||
314 | } | ||
315 | |||
316 | if (cflags & PARENB) | ||
317 | val |= AML_UART_PARITY_EN; | ||
318 | else | ||
319 | val &= ~AML_UART_PARITY_EN; | ||
320 | |||
321 | if (cflags & PARODD) | ||
322 | val |= AML_UART_PARITY_TYPE; | ||
323 | else | ||
324 | val &= ~AML_UART_PARITY_TYPE; | ||
325 | |||
326 | val &= ~AML_UART_STOP_BIN_LEN_MASK; | ||
327 | if (cflags & CSTOPB) | ||
328 | val |= AML_UART_STOP_BIN_2SB; | ||
329 | else | ||
330 | val &= ~AML_UART_STOP_BIN_1SB; | ||
331 | |||
332 | if (cflags & CRTSCTS) | ||
333 | val &= ~AML_UART_TWO_WIRE_EN; | ||
334 | else | ||
335 | val |= AML_UART_TWO_WIRE_EN; | ||
336 | |||
337 | writel(val, port->membase + AML_UART_CONTROL); | ||
338 | |||
339 | baud = uart_get_baud_rate(port, termios, old, 9600, 115200); | ||
340 | meson_uart_change_speed(port, baud); | ||
341 | |||
342 | port->read_status_mask = AML_UART_TX_FIFO_WERR; | ||
343 | if (iflags & INPCK) | ||
344 | port->read_status_mask |= AML_UART_PARITY_ERR | | ||
345 | AML_UART_FRAME_ERR; | ||
346 | |||
347 | port->ignore_status_mask = 0; | ||
348 | if (iflags & IGNPAR) | ||
349 | port->ignore_status_mask |= AML_UART_PARITY_ERR | | ||
350 | AML_UART_FRAME_ERR; | ||
351 | |||
352 | uart_update_timeout(port, termios->c_cflag, baud); | ||
353 | spin_unlock_irqrestore(&port->lock, flags); | ||
354 | } | ||
355 | |||
356 | static int meson_uart_verify_port(struct uart_port *port, | ||
357 | struct serial_struct *ser) | ||
358 | { | ||
359 | int ret = 0; | ||
360 | |||
361 | if (port->type != PORT_MESON) | ||
362 | ret = -EINVAL; | ||
363 | if (port->irq != ser->irq) | ||
364 | ret = -EINVAL; | ||
365 | if (ser->baud_base < 9600) | ||
366 | ret = -EINVAL; | ||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | static void meson_uart_release_port(struct uart_port *port) | ||
371 | { | ||
372 | if (port->flags & UPF_IOREMAP) { | ||
373 | iounmap(port->membase); | ||
374 | port->membase = NULL; | ||
375 | } | ||
376 | } | ||
377 | |||
378 | static int meson_uart_request_port(struct uart_port *port) | ||
379 | { | ||
380 | struct platform_device *pdev = to_platform_device(port->dev); | ||
381 | struct resource *res; | ||
382 | int size; | ||
383 | |||
384 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
385 | if (!res) { | ||
386 | dev_err(&pdev->dev, "cannot obtain I/O memory region"); | ||
387 | return -ENODEV; | ||
388 | } | ||
389 | size = resource_size(res); | ||
390 | |||
391 | if (!devm_request_mem_region(port->dev, port->mapbase, size, | ||
392 | dev_name(port->dev))) { | ||
393 | dev_err(port->dev, "Memory region busy\n"); | ||
394 | return -EBUSY; | ||
395 | } | ||
396 | |||
397 | if (port->flags & UPF_IOREMAP) { | ||
398 | port->membase = devm_ioremap_nocache(port->dev, | ||
399 | port->mapbase, | ||
400 | size); | ||
401 | if (port->membase == NULL) | ||
402 | return -ENOMEM; | ||
403 | } | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static void meson_uart_config_port(struct uart_port *port, int flags) | ||
409 | { | ||
410 | if (flags & UART_CONFIG_TYPE) { | ||
411 | port->type = PORT_MESON; | ||
412 | meson_uart_request_port(port); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | static struct uart_ops meson_uart_ops = { | ||
417 | .set_mctrl = meson_uart_set_mctrl, | ||
418 | .get_mctrl = meson_uart_get_mctrl, | ||
419 | .tx_empty = meson_uart_tx_empty, | ||
420 | .start_tx = meson_uart_start_tx, | ||
421 | .stop_tx = meson_uart_stop_tx, | ||
422 | .stop_rx = meson_uart_stop_rx, | ||
423 | .startup = meson_uart_startup, | ||
424 | .shutdown = meson_uart_shutdown, | ||
425 | .set_termios = meson_uart_set_termios, | ||
426 | .type = meson_uart_type, | ||
427 | .config_port = meson_uart_config_port, | ||
428 | .request_port = meson_uart_request_port, | ||
429 | .release_port = meson_uart_release_port, | ||
430 | .verify_port = meson_uart_verify_port, | ||
431 | }; | ||
432 | |||
433 | #ifdef CONFIG_SERIAL_MESON_CONSOLE | ||
434 | |||
435 | static void meson_console_putchar(struct uart_port *port, int ch) | ||
436 | { | ||
437 | if (!port->membase) | ||
438 | return; | ||
439 | |||
440 | while (readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL) | ||
441 | cpu_relax(); | ||
442 | writel(ch, port->membase + AML_UART_WFIFO); | ||
443 | } | ||
444 | |||
445 | static void meson_serial_console_write(struct console *co, const char *s, | ||
446 | u_int count) | ||
447 | { | ||
448 | struct uart_port *port; | ||
449 | unsigned long flags; | ||
450 | int locked; | ||
451 | |||
452 | port = meson_ports[co->index]; | ||
453 | if (!port) | ||
454 | return; | ||
455 | |||
456 | local_irq_save(flags); | ||
457 | if (port->sysrq) { | ||
458 | locked = 0; | ||
459 | } else if (oops_in_progress) { | ||
460 | locked = spin_trylock(&port->lock); | ||
461 | } else { | ||
462 | spin_lock(&port->lock); | ||
463 | locked = 1; | ||
464 | } | ||
465 | |||
466 | uart_console_write(port, s, count, meson_console_putchar); | ||
467 | |||
468 | if (locked) | ||
469 | spin_unlock(&port->lock); | ||
470 | local_irq_restore(flags); | ||
471 | } | ||
472 | |||
473 | static int meson_serial_console_setup(struct console *co, char *options) | ||
474 | { | ||
475 | struct uart_port *port; | ||
476 | int baud = 115200; | ||
477 | int bits = 8; | ||
478 | int parity = 'n'; | ||
479 | int flow = 'n'; | ||
480 | |||
481 | if (co->index < 0 || co->index >= AML_UART_PORT_NUM) | ||
482 | return -EINVAL; | ||
483 | |||
484 | port = meson_ports[co->index]; | ||
485 | if (!port || !port->membase) | ||
486 | return -ENODEV; | ||
487 | |||
488 | if (options) | ||
489 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
490 | |||
491 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
492 | } | ||
493 | |||
494 | static struct console meson_serial_console = { | ||
495 | .name = AML_UART_DEV_NAME, | ||
496 | .write = meson_serial_console_write, | ||
497 | .device = uart_console_device, | ||
498 | .setup = meson_serial_console_setup, | ||
499 | .flags = CON_PRINTBUFFER, | ||
500 | .index = -1, | ||
501 | .data = &meson_uart_driver, | ||
502 | }; | ||
503 | |||
504 | static int __init meson_serial_console_init(void) | ||
505 | { | ||
506 | register_console(&meson_serial_console); | ||
507 | return 0; | ||
508 | } | ||
509 | console_initcall(meson_serial_console_init); | ||
510 | |||
511 | #define MESON_SERIAL_CONSOLE (&meson_serial_console) | ||
512 | #else | ||
513 | #define MESON_SERIAL_CONSOLE NULL | ||
514 | #endif | ||
515 | |||
516 | static struct uart_driver meson_uart_driver = { | ||
517 | .owner = THIS_MODULE, | ||
518 | .driver_name = "meson_uart", | ||
519 | .dev_name = AML_UART_DEV_NAME, | ||
520 | .nr = AML_UART_PORT_NUM, | ||
521 | .cons = MESON_SERIAL_CONSOLE, | ||
522 | }; | ||
523 | |||
524 | static int meson_uart_probe(struct platform_device *pdev) | ||
525 | { | ||
526 | struct resource *res_mem, *res_irq; | ||
527 | struct uart_port *port; | ||
528 | struct clk *clk; | ||
529 | int ret = 0; | ||
530 | |||
531 | if (pdev->dev.of_node) | ||
532 | pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); | ||
533 | |||
534 | if (pdev->id < 0 || pdev->id >= AML_UART_PORT_NUM) | ||
535 | return -EINVAL; | ||
536 | |||
537 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
538 | if (!res_mem) | ||
539 | return -ENODEV; | ||
540 | |||
541 | res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
542 | if (!res_irq) | ||
543 | return -ENODEV; | ||
544 | |||
545 | if (meson_ports[pdev->id]) { | ||
546 | dev_err(&pdev->dev, "port %d already allocated\n", pdev->id); | ||
547 | return -EBUSY; | ||
548 | } | ||
549 | |||
550 | port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL); | ||
551 | if (!port) | ||
552 | return -ENOMEM; | ||
553 | |||
554 | clk = clk_get(&pdev->dev, NULL); | ||
555 | if (IS_ERR(clk)) | ||
556 | return PTR_ERR(clk); | ||
557 | |||
558 | port->uartclk = clk_get_rate(clk); | ||
559 | port->iotype = UPIO_MEM; | ||
560 | port->mapbase = res_mem->start; | ||
561 | port->irq = res_irq->start; | ||
562 | port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_LOW_LATENCY; | ||
563 | port->dev = &pdev->dev; | ||
564 | port->line = pdev->id; | ||
565 | port->type = PORT_MESON; | ||
566 | port->x_char = 0; | ||
567 | port->ops = &meson_uart_ops; | ||
568 | port->fifosize = 64; | ||
569 | |||
570 | meson_ports[pdev->id] = port; | ||
571 | platform_set_drvdata(pdev, port); | ||
572 | |||
573 | ret = uart_add_one_port(&meson_uart_driver, port); | ||
574 | if (ret) | ||
575 | meson_ports[pdev->id] = NULL; | ||
576 | |||
577 | return ret; | ||
578 | } | ||
579 | |||
580 | static int meson_uart_remove(struct platform_device *pdev) | ||
581 | { | ||
582 | struct uart_port *port; | ||
583 | |||
584 | port = platform_get_drvdata(pdev); | ||
585 | uart_remove_one_port(&meson_uart_driver, port); | ||
586 | meson_ports[pdev->id] = NULL; | ||
587 | |||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | |||
592 | static const struct of_device_id meson_uart_dt_match[] = { | ||
593 | { .compatible = "amlogic,meson-uart" }, | ||
594 | { /* sentinel */ }, | ||
595 | }; | ||
596 | MODULE_DEVICE_TABLE(of, meson_uart_dt_match); | ||
597 | |||
598 | static struct platform_driver meson_uart_platform_driver = { | ||
599 | .probe = meson_uart_probe, | ||
600 | .remove = meson_uart_remove, | ||
601 | .driver = { | ||
602 | .owner = THIS_MODULE, | ||
603 | .name = "meson_uart", | ||
604 | .of_match_table = meson_uart_dt_match, | ||
605 | }, | ||
606 | }; | ||
607 | |||
608 | static int __init meson_uart_init(void) | ||
609 | { | ||
610 | int ret; | ||
611 | |||
612 | ret = uart_register_driver(&meson_uart_driver); | ||
613 | if (ret) | ||
614 | return ret; | ||
615 | |||
616 | ret = platform_driver_register(&meson_uart_platform_driver); | ||
617 | if (ret) | ||
618 | uart_unregister_driver(&meson_uart_driver); | ||
619 | |||
620 | return ret; | ||
621 | } | ||
622 | |||
623 | static void __exit meson_uart_exit(void) | ||
624 | { | ||
625 | platform_driver_unregister(&meson_uart_platform_driver); | ||
626 | uart_unregister_driver(&meson_uart_driver); | ||
627 | } | ||
628 | |||
629 | module_init(meson_uart_init); | ||
630 | module_exit(meson_uart_exit); | ||
631 | |||
632 | MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); | ||
633 | MODULE_DESCRIPTION("Amlogic Meson serial port driver"); | ||
634 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 97888f4900ec..a5f4e3648b15 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -1087,22 +1087,6 @@ mpc52xx_uart_start_tx(struct uart_port *port) | |||
1087 | } | 1087 | } |
1088 | 1088 | ||
1089 | static void | 1089 | static void |
1090 | mpc52xx_uart_send_xchar(struct uart_port *port, char ch) | ||
1091 | { | ||
1092 | unsigned long flags; | ||
1093 | spin_lock_irqsave(&port->lock, flags); | ||
1094 | |||
1095 | port->x_char = ch; | ||
1096 | if (ch) { | ||
1097 | /* Make sure tx interrupts are on */ | ||
1098 | /* Truly necessary ??? They should be anyway */ | ||
1099 | psc_ops->start_tx(port); | ||
1100 | } | ||
1101 | |||
1102 | spin_unlock_irqrestore(&port->lock, flags); | ||
1103 | } | ||
1104 | |||
1105 | static void | ||
1106 | mpc52xx_uart_stop_rx(struct uart_port *port) | 1090 | mpc52xx_uart_stop_rx(struct uart_port *port) |
1107 | { | 1091 | { |
1108 | /* port->lock taken by caller */ | 1092 | /* port->lock taken by caller */ |
@@ -1361,7 +1345,6 @@ static struct uart_ops mpc52xx_uart_ops = { | |||
1361 | .get_mctrl = mpc52xx_uart_get_mctrl, | 1345 | .get_mctrl = mpc52xx_uart_get_mctrl, |
1362 | .stop_tx = mpc52xx_uart_stop_tx, | 1346 | .stop_tx = mpc52xx_uart_stop_tx, |
1363 | .start_tx = mpc52xx_uart_start_tx, | 1347 | .start_tx = mpc52xx_uart_start_tx, |
1364 | .send_xchar = mpc52xx_uart_send_xchar, | ||
1365 | .stop_rx = mpc52xx_uart_stop_rx, | 1348 | .stop_rx = mpc52xx_uart_stop_rx, |
1366 | .enable_ms = mpc52xx_uart_enable_ms, | 1349 | .enable_ms = mpc52xx_uart_enable_ms, |
1367 | .break_ctl = mpc52xx_uart_break_ctl, | 1350 | .break_ctl = mpc52xx_uart_break_ctl, |
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 0da0b5474e98..4b6c78331a64 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -190,11 +190,10 @@ static void handle_rx(struct uart_port *port) | |||
190 | /* Mask conditions we're ignorning. */ | 190 | /* Mask conditions we're ignorning. */ |
191 | sr &= port->read_status_mask; | 191 | sr &= port->read_status_mask; |
192 | 192 | ||
193 | if (sr & UART_SR_RX_BREAK) { | 193 | if (sr & UART_SR_RX_BREAK) |
194 | flag = TTY_BREAK; | 194 | flag = TTY_BREAK; |
195 | } else if (sr & UART_SR_PAR_FRAME_ERR) { | 195 | else if (sr & UART_SR_PAR_FRAME_ERR) |
196 | flag = TTY_FRAME; | 196 | flag = TTY_FRAME; |
197 | } | ||
198 | 197 | ||
199 | if (!uart_handle_sysrq_char(port, c)) | 198 | if (!uart_handle_sysrq_char(port, c)) |
200 | tty_insert_flip_char(tport, c, flag); | 199 | tty_insert_flip_char(tport, c, flag); |
@@ -315,7 +314,6 @@ static unsigned int msm_get_mctrl(struct uart_port *port) | |||
315 | return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR | TIOCM_RTS; | 314 | return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR | TIOCM_RTS; |
316 | } | 315 | } |
317 | 316 | ||
318 | |||
319 | static void msm_reset(struct uart_port *port) | 317 | static void msm_reset(struct uart_port *port) |
320 | { | 318 | { |
321 | struct msm_port *msm_port = UART_TO_MSM(port); | 319 | struct msm_port *msm_port = UART_TO_MSM(port); |
@@ -336,6 +334,7 @@ static void msm_reset(struct uart_port *port) | |||
336 | static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl) | 334 | static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl) |
337 | { | 335 | { |
338 | unsigned int mr; | 336 | unsigned int mr; |
337 | |||
339 | mr = msm_read(port, UART_MR1); | 338 | mr = msm_read(port, UART_MR1); |
340 | 339 | ||
341 | if (!(mctrl & TIOCM_RTS)) { | 340 | if (!(mctrl & TIOCM_RTS)) { |
@@ -431,7 +430,6 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud) | |||
431 | return baud; | 430 | return baud; |
432 | } | 431 | } |
433 | 432 | ||
434 | |||
435 | static void msm_init_clock(struct uart_port *port) | 433 | static void msm_init_clock(struct uart_port *port) |
436 | { | 434 | { |
437 | struct msm_port *msm_port = UART_TO_MSM(port); | 435 | struct msm_port *msm_port = UART_TO_MSM(port); |
@@ -646,6 +644,7 @@ fail_release_port: | |||
646 | static void msm_config_port(struct uart_port *port, int flags) | 644 | static void msm_config_port(struct uart_port *port, int flags) |
647 | { | 645 | { |
648 | int ret; | 646 | int ret; |
647 | |||
649 | if (flags & UART_CONFIG_TYPE) { | 648 | if (flags & UART_CONFIG_TYPE) { |
650 | port->type = PORT_MSM; | 649 | port->type = PORT_MSM; |
651 | ret = msm_request_port(port); | 650 | ret = msm_request_port(port); |
@@ -678,22 +677,11 @@ static void msm_power(struct uart_port *port, unsigned int state, | |||
678 | clk_disable_unprepare(msm_port->pclk); | 677 | clk_disable_unprepare(msm_port->pclk); |
679 | break; | 678 | break; |
680 | default: | 679 | default: |
681 | printk(KERN_ERR "msm_serial: Unknown PM state %d\n", state); | 680 | pr_err("msm_serial: Unknown PM state %d\n", state); |
682 | } | 681 | } |
683 | } | 682 | } |
684 | 683 | ||
685 | #ifdef CONFIG_CONSOLE_POLL | 684 | #ifdef CONFIG_CONSOLE_POLL |
686 | static int msm_poll_init(struct uart_port *port) | ||
687 | { | ||
688 | struct msm_port *msm_port = UART_TO_MSM(port); | ||
689 | |||
690 | /* Enable single character mode on RX FIFO */ | ||
691 | if (msm_port->is_uartdm >= UARTDM_1P4) | ||
692 | msm_write(port, UARTDM_DMEN_RX_SC_ENABLE, UARTDM_DMEN); | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int msm_poll_get_char_single(struct uart_port *port) | 685 | static int msm_poll_get_char_single(struct uart_port *port) |
698 | { | 686 | { |
699 | struct msm_port *msm_port = UART_TO_MSM(port); | 687 | struct msm_port *msm_port = UART_TO_MSM(port); |
@@ -701,11 +689,11 @@ static int msm_poll_get_char_single(struct uart_port *port) | |||
701 | 689 | ||
702 | if (!(msm_read(port, UART_SR) & UART_SR_RX_READY)) | 690 | if (!(msm_read(port, UART_SR) & UART_SR_RX_READY)) |
703 | return NO_POLL_CHAR; | 691 | return NO_POLL_CHAR; |
704 | else | 692 | |
705 | return msm_read(port, rf_reg) & 0xff; | 693 | return msm_read(port, rf_reg) & 0xff; |
706 | } | 694 | } |
707 | 695 | ||
708 | static int msm_poll_get_char_dm_1p3(struct uart_port *port) | 696 | static int msm_poll_get_char_dm(struct uart_port *port) |
709 | { | 697 | { |
710 | int c; | 698 | int c; |
711 | static u32 slop; | 699 | static u32 slop; |
@@ -729,6 +717,10 @@ static int msm_poll_get_char_dm_1p3(struct uart_port *port) | |||
729 | slop = msm_read(port, UARTDM_RF); | 717 | slop = msm_read(port, UARTDM_RF); |
730 | c = sp[0]; | 718 | c = sp[0]; |
731 | count--; | 719 | count--; |
720 | msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); | ||
721 | msm_write(port, 0xFFFFFF, UARTDM_DMRX); | ||
722 | msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, | ||
723 | UART_CR); | ||
732 | } else { | 724 | } else { |
733 | c = NO_POLL_CHAR; | 725 | c = NO_POLL_CHAR; |
734 | } | 726 | } |
@@ -752,8 +744,8 @@ static int msm_poll_get_char(struct uart_port *port) | |||
752 | imr = msm_read(port, UART_IMR); | 744 | imr = msm_read(port, UART_IMR); |
753 | msm_write(port, 0, UART_IMR); | 745 | msm_write(port, 0, UART_IMR); |
754 | 746 | ||
755 | if (msm_port->is_uartdm == UARTDM_1P3) | 747 | if (msm_port->is_uartdm) |
756 | c = msm_poll_get_char_dm_1p3(port); | 748 | c = msm_poll_get_char_dm(port); |
757 | else | 749 | else |
758 | c = msm_poll_get_char_single(port); | 750 | c = msm_poll_get_char_single(port); |
759 | 751 | ||
@@ -788,8 +780,6 @@ static void msm_poll_put_char(struct uart_port *port, unsigned char c) | |||
788 | 780 | ||
789 | /* Enable interrupts */ | 781 | /* Enable interrupts */ |
790 | msm_write(port, imr, UART_IMR); | 782 | msm_write(port, imr, UART_IMR); |
791 | |||
792 | return; | ||
793 | } | 783 | } |
794 | #endif | 784 | #endif |
795 | 785 | ||
@@ -812,7 +802,6 @@ static struct uart_ops msm_uart_pops = { | |||
812 | .verify_port = msm_verify_port, | 802 | .verify_port = msm_verify_port, |
813 | .pm = msm_power, | 803 | .pm = msm_power, |
814 | #ifdef CONFIG_CONSOLE_POLL | 804 | #ifdef CONFIG_CONSOLE_POLL |
815 | .poll_init = msm_poll_init, | ||
816 | .poll_get_char = msm_poll_get_char, | 805 | .poll_get_char = msm_poll_get_char, |
817 | .poll_put_char = msm_poll_put_char, | 806 | .poll_put_char = msm_poll_put_char, |
818 | #endif | 807 | #endif |
@@ -856,22 +845,15 @@ static inline struct uart_port *get_port_from_line(unsigned int line) | |||
856 | } | 845 | } |
857 | 846 | ||
858 | #ifdef CONFIG_SERIAL_MSM_CONSOLE | 847 | #ifdef CONFIG_SERIAL_MSM_CONSOLE |
859 | static void msm_console_write(struct console *co, const char *s, | 848 | static void __msm_console_write(struct uart_port *port, const char *s, |
860 | unsigned int count) | 849 | unsigned int count, bool is_uartdm) |
861 | { | 850 | { |
862 | int i; | 851 | int i; |
863 | struct uart_port *port; | ||
864 | struct msm_port *msm_port; | ||
865 | int num_newlines = 0; | 852 | int num_newlines = 0; |
866 | bool replaced = false; | 853 | bool replaced = false; |
867 | void __iomem *tf; | 854 | void __iomem *tf; |
868 | 855 | ||
869 | BUG_ON(co->index < 0 || co->index >= UART_NR); | 856 | if (is_uartdm) |
870 | |||
871 | port = get_port_from_line(co->index); | ||
872 | msm_port = UART_TO_MSM(port); | ||
873 | |||
874 | if (msm_port->is_uartdm) | ||
875 | tf = port->membase + UARTDM_TF; | 857 | tf = port->membase + UARTDM_TF; |
876 | else | 858 | else |
877 | tf = port->membase + UART_TF; | 859 | tf = port->membase + UART_TF; |
@@ -883,7 +865,7 @@ static void msm_console_write(struct console *co, const char *s, | |||
883 | count += num_newlines; | 865 | count += num_newlines; |
884 | 866 | ||
885 | spin_lock(&port->lock); | 867 | spin_lock(&port->lock); |
886 | if (msm_port->is_uartdm) | 868 | if (is_uartdm) |
887 | reset_dm_count(port, count); | 869 | reset_dm_count(port, count); |
888 | 870 | ||
889 | i = 0; | 871 | i = 0; |
@@ -892,7 +874,7 @@ static void msm_console_write(struct console *co, const char *s, | |||
892 | unsigned int num_chars; | 874 | unsigned int num_chars; |
893 | char buf[4] = { 0 }; | 875 | char buf[4] = { 0 }; |
894 | 876 | ||
895 | if (msm_port->is_uartdm) | 877 | if (is_uartdm) |
896 | num_chars = min(count - i, (unsigned int)sizeof(buf)); | 878 | num_chars = min(count - i, (unsigned int)sizeof(buf)); |
897 | else | 879 | else |
898 | num_chars = 1; | 880 | num_chars = 1; |
@@ -921,6 +903,20 @@ static void msm_console_write(struct console *co, const char *s, | |||
921 | spin_unlock(&port->lock); | 903 | spin_unlock(&port->lock); |
922 | } | 904 | } |
923 | 905 | ||
906 | static void msm_console_write(struct console *co, const char *s, | ||
907 | unsigned int count) | ||
908 | { | ||
909 | struct uart_port *port; | ||
910 | struct msm_port *msm_port; | ||
911 | |||
912 | BUG_ON(co->index < 0 || co->index >= UART_NR); | ||
913 | |||
914 | port = get_port_from_line(co->index); | ||
915 | msm_port = UART_TO_MSM(port); | ||
916 | |||
917 | __msm_console_write(port, s, count, msm_port->is_uartdm); | ||
918 | } | ||
919 | |||
924 | static int __init msm_console_setup(struct console *co, char *options) | 920 | static int __init msm_console_setup(struct console *co, char *options) |
925 | { | 921 | { |
926 | struct uart_port *port; | 922 | struct uart_port *port; |
@@ -958,11 +954,54 @@ static int __init msm_console_setup(struct console *co, char *options) | |||
958 | msm_write(port, UART_CR_TX_ENABLE, UART_CR); | 954 | msm_write(port, UART_CR_TX_ENABLE, UART_CR); |
959 | } | 955 | } |
960 | 956 | ||
961 | printk(KERN_INFO "msm_serial: console setup on port #%d\n", port->line); | 957 | pr_info("msm_serial: console setup on port #%d\n", port->line); |
962 | 958 | ||
963 | return uart_set_options(port, co, baud, parity, bits, flow); | 959 | return uart_set_options(port, co, baud, parity, bits, flow); |
964 | } | 960 | } |
965 | 961 | ||
962 | static void | ||
963 | msm_serial_early_write(struct console *con, const char *s, unsigned n) | ||
964 | { | ||
965 | struct earlycon_device *dev = con->data; | ||
966 | |||
967 | __msm_console_write(&dev->port, s, n, false); | ||
968 | } | ||
969 | |||
970 | static int __init | ||
971 | msm_serial_early_console_setup(struct earlycon_device *device, const char *opt) | ||
972 | { | ||
973 | if (!device->port.membase) | ||
974 | return -ENODEV; | ||
975 | |||
976 | device->con->write = msm_serial_early_write; | ||
977 | return 0; | ||
978 | } | ||
979 | EARLYCON_DECLARE(msm_serial, msm_serial_early_console_setup); | ||
980 | OF_EARLYCON_DECLARE(msm_serial, "qcom,msm-uart", | ||
981 | msm_serial_early_console_setup); | ||
982 | |||
983 | static void | ||
984 | msm_serial_early_write_dm(struct console *con, const char *s, unsigned n) | ||
985 | { | ||
986 | struct earlycon_device *dev = con->data; | ||
987 | |||
988 | __msm_console_write(&dev->port, s, n, true); | ||
989 | } | ||
990 | |||
991 | static int __init | ||
992 | msm_serial_early_console_setup_dm(struct earlycon_device *device, | ||
993 | const char *opt) | ||
994 | { | ||
995 | if (!device->port.membase) | ||
996 | return -ENODEV; | ||
997 | |||
998 | device->con->write = msm_serial_early_write_dm; | ||
999 | return 0; | ||
1000 | } | ||
1001 | EARLYCON_DECLARE(msm_serial_dm, msm_serial_early_console_setup_dm); | ||
1002 | OF_EARLYCON_DECLARE(msm_serial_dm, "qcom,msm-uartdm", | ||
1003 | msm_serial_early_console_setup_dm); | ||
1004 | |||
966 | static struct uart_driver msm_uart_driver; | 1005 | static struct uart_driver msm_uart_driver; |
967 | 1006 | ||
968 | static struct console msm_console = { | 1007 | static struct console msm_console = { |
@@ -1013,7 +1052,7 @@ static int msm_serial_probe(struct platform_device *pdev) | |||
1013 | if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) | 1052 | if (unlikely(pdev->id < 0 || pdev->id >= UART_NR)) |
1014 | return -ENXIO; | 1053 | return -ENXIO; |
1015 | 1054 | ||
1016 | printk(KERN_INFO "msm_serial: detected port #%d\n", pdev->id); | 1055 | dev_info(&pdev->dev, "msm_serial: detected port #%d\n", pdev->id); |
1017 | 1056 | ||
1018 | port = get_port_from_line(pdev->id); | 1057 | port = get_port_from_line(pdev->id); |
1019 | port->dev = &pdev->dev; | 1058 | port->dev = &pdev->dev; |
@@ -1038,8 +1077,7 @@ static int msm_serial_probe(struct platform_device *pdev) | |||
1038 | } | 1077 | } |
1039 | 1078 | ||
1040 | port->uartclk = clk_get_rate(msm_port->clk); | 1079 | port->uartclk = clk_get_rate(msm_port->clk); |
1041 | printk(KERN_INFO "uartclk = %d\n", port->uartclk); | 1080 | dev_info(&pdev->dev, "uartclk = %d\n", port->uartclk); |
1042 | |||
1043 | 1081 | ||
1044 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1082 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1045 | if (unlikely(!resource)) | 1083 | if (unlikely(!resource)) |
@@ -1093,7 +1131,7 @@ static int __init msm_serial_init(void) | |||
1093 | if (unlikely(ret)) | 1131 | if (unlikely(ret)) |
1094 | uart_unregister_driver(&msm_uart_driver); | 1132 | uart_unregister_driver(&msm_uart_driver); |
1095 | 1133 | ||
1096 | printk(KERN_INFO "msm_serial: driver initialized\n"); | 1134 | pr_info("msm_serial: driver initialized\n"); |
1097 | 1135 | ||
1098 | return ret; | 1136 | return ret; |
1099 | } | 1137 | } |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index b5c329248c81..10c29334fe2f 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -408,7 +408,7 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
408 | 408 | ||
409 | ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS); | 409 | ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS); |
410 | if (mctrl & TIOCM_RTS) { | 410 | if (mctrl & TIOCM_RTS) { |
411 | if (tty_port_cts_enabled(&u->state->port)) | 411 | if (uart_cts_enabled(u)) |
412 | ctrl |= AUART_CTRL2_RTSEN; | 412 | ctrl |= AUART_CTRL2_RTSEN; |
413 | else | 413 | else |
414 | ctrl |= AUART_CTRL2_RTS; | 414 | ctrl |= AUART_CTRL2_RTS; |
diff --git a/drivers/tty/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c index c06366b6bc29..5da7622e88c3 100644 --- a/drivers/tty/serial/nwpserial.c +++ b/drivers/tty/serial/nwpserial.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/of_platform.h> | 22 | #include <linux/of_platform.h> |
23 | #include <linux/of_device.h> | 23 | #include <linux/of_device.h> |
24 | #include <linux/nwpserial.h> | 24 | #include <linux/nwpserial.h> |
25 | #include <linux/delay.h> | ||
25 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
26 | #include <asm/dcr.h> | 27 | #include <asm/dcr.h> |
27 | 28 | ||
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 68d4455f3cf9..8bc2563335ae 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -183,10 +183,6 @@ static int of_platform_serial_probe(struct platform_device *ofdev) | |||
183 | "auto-flow-control")) | 183 | "auto-flow-control")) |
184 | port8250.capabilities |= UART_CAP_AFE; | 184 | port8250.capabilities |= UART_CAP_AFE; |
185 | 185 | ||
186 | if (of_property_read_bool(ofdev->dev.of_node, | ||
187 | "has-hw-flow-control")) | ||
188 | port8250.port.flags |= UPF_HARD_FLOW; | ||
189 | |||
190 | ret = serial8250_register_8250_port(&port8250); | 186 | ret = serial8250_register_8250_port(&port8250); |
191 | break; | 187 | break; |
192 | } | 188 | } |
@@ -244,6 +240,32 @@ static int of_platform_serial_remove(struct platform_device *ofdev) | |||
244 | return 0; | 240 | return 0; |
245 | } | 241 | } |
246 | 242 | ||
243 | #ifdef CONFIG_PM_SLEEP | ||
244 | static int of_serial_suspend(struct device *dev) | ||
245 | { | ||
246 | struct of_serial_info *info = dev_get_drvdata(dev); | ||
247 | |||
248 | serial8250_suspend_port(info->line); | ||
249 | if (info->clk) | ||
250 | clk_disable_unprepare(info->clk); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | static int of_serial_resume(struct device *dev) | ||
256 | { | ||
257 | struct of_serial_info *info = dev_get_drvdata(dev); | ||
258 | |||
259 | if (info->clk) | ||
260 | clk_prepare_enable(info->clk); | ||
261 | |||
262 | serial8250_resume_port(info->line); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | #endif | ||
267 | static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume); | ||
268 | |||
247 | /* | 269 | /* |
248 | * A few common types, add more as needed. | 270 | * A few common types, add more as needed. |
249 | */ | 271 | */ |
@@ -275,6 +297,7 @@ static struct platform_driver of_platform_serial_driver = { | |||
275 | .name = "of_serial", | 297 | .name = "of_serial", |
276 | .owner = THIS_MODULE, | 298 | .owner = THIS_MODULE, |
277 | .of_match_table = of_platform_serial_table, | 299 | .of_match_table = of_platform_serial_table, |
300 | .pm = &of_serial_pm_ops, | ||
278 | }, | 301 | }, |
279 | .probe = of_platform_serial_probe, | 302 | .probe = of_platform_serial_probe, |
280 | .remove = of_platform_serial_remove, | 303 | .remove = of_platform_serial_remove, |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d017cec8a34a..18c30cabe27f 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -239,6 +239,26 @@ static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | |||
239 | } | 239 | } |
240 | 240 | ||
241 | /* | 241 | /* |
242 | * Calculate the absolute difference between the desired and actual baud | ||
243 | * rate for the given mode. | ||
244 | */ | ||
245 | static inline int calculate_baud_abs_diff(struct uart_port *port, | ||
246 | unsigned int baud, unsigned int mode) | ||
247 | { | ||
248 | unsigned int n = port->uartclk / (mode * baud); | ||
249 | int abs_diff; | ||
250 | |||
251 | if (n == 0) | ||
252 | n = 1; | ||
253 | |||
254 | abs_diff = baud - (port->uartclk / (mode * n)); | ||
255 | if (abs_diff < 0) | ||
256 | abs_diff = -abs_diff; | ||
257 | |||
258 | return abs_diff; | ||
259 | } | ||
260 | |||
261 | /* | ||
242 | * serial_omap_baud_is_mode16 - check if baud rate is MODE16X | 262 | * serial_omap_baud_is_mode16 - check if baud rate is MODE16X |
243 | * @port: uart port info | 263 | * @port: uart port info |
244 | * @baud: baudrate for which mode needs to be determined | 264 | * @baud: baudrate for which mode needs to be determined |
@@ -252,16 +272,10 @@ static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | |||
252 | static bool | 272 | static bool |
253 | serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud) | 273 | serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud) |
254 | { | 274 | { |
255 | unsigned int n13 = port->uartclk / (13 * baud); | 275 | int abs_diff_13 = calculate_baud_abs_diff(port, baud, 13); |
256 | unsigned int n16 = port->uartclk / (16 * baud); | 276 | int abs_diff_16 = calculate_baud_abs_diff(port, baud, 16); |
257 | int baudAbsDiff13 = baud - (port->uartclk / (13 * n13)); | 277 | |
258 | int baudAbsDiff16 = baud - (port->uartclk / (16 * n16)); | 278 | return (abs_diff_13 >= abs_diff_16); |
259 | if (baudAbsDiff13 < 0) | ||
260 | baudAbsDiff13 = -baudAbsDiff13; | ||
261 | if (baudAbsDiff16 < 0) | ||
262 | baudAbsDiff16 = -baudAbsDiff16; | ||
263 | |||
264 | return (baudAbsDiff13 >= baudAbsDiff16); | ||
265 | } | 279 | } |
266 | 280 | ||
267 | /* | 281 | /* |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 29a7be47389a..df3a8c74358e 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -59,6 +59,11 @@ static void uart_change_pm(struct uart_state *state, | |||
59 | 59 | ||
60 | static void uart_port_shutdown(struct tty_port *port); | 60 | static void uart_port_shutdown(struct tty_port *port); |
61 | 61 | ||
62 | static int uart_dcd_enabled(struct uart_port *uport) | ||
63 | { | ||
64 | return uport->status & UPSTAT_DCD_ENABLE; | ||
65 | } | ||
66 | |||
62 | /* | 67 | /* |
63 | * This routine is used by the interrupt handler to schedule processing in | 68 | * This routine is used by the interrupt handler to schedule processing in |
64 | * the software interrupt portion of the driver. | 69 | * the software interrupt portion of the driver. |
@@ -90,7 +95,7 @@ static void __uart_start(struct tty_struct *tty) | |||
90 | struct uart_state *state = tty->driver_data; | 95 | struct uart_state *state = tty->driver_data; |
91 | struct uart_port *port = state->uart_port; | 96 | struct uart_port *port = state->uart_port; |
92 | 97 | ||
93 | if (!tty->stopped && !tty->hw_stopped) | 98 | if (!uart_tx_stopped(port)) |
94 | port->ops->start_tx(port); | 99 | port->ops->start_tx(port); |
95 | } | 100 | } |
96 | 101 | ||
@@ -130,7 +135,6 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
130 | int init_hw) | 135 | int init_hw) |
131 | { | 136 | { |
132 | struct uart_port *uport = state->uart_port; | 137 | struct uart_port *uport = state->uart_port; |
133 | struct tty_port *port = &state->port; | ||
134 | unsigned long page; | 138 | unsigned long page; |
135 | int retval = 0; | 139 | int retval = 0; |
136 | 140 | ||
@@ -175,17 +179,14 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
175 | if (tty->termios.c_cflag & CBAUD) | 179 | if (tty->termios.c_cflag & CBAUD) |
176 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); | 180 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); |
177 | } | 181 | } |
178 | /* | 182 | |
179 | * if hw support flow control without software intervention, | 183 | spin_lock_irq(&uport->lock); |
180 | * then skip the below check | 184 | if (uart_cts_enabled(uport) && |
181 | */ | 185 | !(uport->ops->get_mctrl(uport) & TIOCM_CTS)) |
182 | if (tty_port_cts_enabled(port) && | 186 | uport->hw_stopped = 1; |
183 | !(uport->flags & UPF_HARD_FLOW)) { | 187 | else |
184 | spin_lock_irq(&uport->lock); | 188 | uport->hw_stopped = 0; |
185 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) | 189 | spin_unlock_irq(&uport->lock); |
186 | tty->hw_stopped = 1; | ||
187 | spin_unlock_irq(&uport->lock); | ||
188 | } | ||
189 | } | 190 | } |
190 | 191 | ||
191 | /* | 192 | /* |
@@ -439,7 +440,6 @@ EXPORT_SYMBOL(uart_get_divisor); | |||
439 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | 440 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
440 | struct ktermios *old_termios) | 441 | struct ktermios *old_termios) |
441 | { | 442 | { |
442 | struct tty_port *port = &state->port; | ||
443 | struct uart_port *uport = state->uart_port; | 443 | struct uart_port *uport = state->uart_port; |
444 | struct ktermios *termios; | 444 | struct ktermios *termios; |
445 | 445 | ||
@@ -454,17 +454,19 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | |||
454 | uport->ops->set_termios(uport, termios, old_termios); | 454 | uport->ops->set_termios(uport, termios, old_termios); |
455 | 455 | ||
456 | /* | 456 | /* |
457 | * Set flags based on termios cflag | 457 | * Set modem status enables based on termios cflag |
458 | */ | 458 | */ |
459 | spin_lock_irq(&uport->lock); | ||
459 | if (termios->c_cflag & CRTSCTS) | 460 | if (termios->c_cflag & CRTSCTS) |
460 | set_bit(ASYNCB_CTS_FLOW, &port->flags); | 461 | uport->status |= UPSTAT_CTS_ENABLE; |
461 | else | 462 | else |
462 | clear_bit(ASYNCB_CTS_FLOW, &port->flags); | 463 | uport->status &= ~UPSTAT_CTS_ENABLE; |
463 | 464 | ||
464 | if (termios->c_cflag & CLOCAL) | 465 | if (termios->c_cflag & CLOCAL) |
465 | clear_bit(ASYNCB_CHECK_CD, &port->flags); | 466 | uport->status &= ~UPSTAT_DCD_ENABLE; |
466 | else | 467 | else |
467 | set_bit(ASYNCB_CHECK_CD, &port->flags); | 468 | uport->status |= UPSTAT_DCD_ENABLE; |
469 | spin_unlock_irq(&uport->lock); | ||
468 | } | 470 | } |
469 | 471 | ||
470 | static inline int __uart_put_char(struct uart_port *port, | 472 | static inline int __uart_put_char(struct uart_port *port, |
@@ -604,12 +606,11 @@ static void uart_send_xchar(struct tty_struct *tty, char ch) | |||
604 | if (port->ops->send_xchar) | 606 | if (port->ops->send_xchar) |
605 | port->ops->send_xchar(port, ch); | 607 | port->ops->send_xchar(port, ch); |
606 | else { | 608 | else { |
609 | spin_lock_irqsave(&port->lock, flags); | ||
607 | port->x_char = ch; | 610 | port->x_char = ch; |
608 | if (ch) { | 611 | if (ch) |
609 | spin_lock_irqsave(&port->lock, flags); | ||
610 | port->ops->start_tx(port); | 612 | port->ops->start_tx(port); |
611 | spin_unlock_irqrestore(&port->lock, flags); | 613 | spin_unlock_irqrestore(&port->lock, flags); |
612 | } | ||
613 | } | 614 | } |
614 | } | 615 | } |
615 | 616 | ||
@@ -652,12 +653,8 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
652 | mask &= ~port->flags; | 653 | mask &= ~port->flags; |
653 | } | 654 | } |
654 | 655 | ||
655 | if (mask & UPF_SOFT_FLOW) { | 656 | if (mask & UPF_SOFT_FLOW) |
656 | if (port->x_char) | 657 | uart_send_xchar(tty, START_CHAR(tty)); |
657 | port->x_char = 0; | ||
658 | else | ||
659 | uart_send_xchar(tty, START_CHAR(tty)); | ||
660 | } | ||
661 | 658 | ||
662 | if (mask & UPF_HARD_FLOW) | 659 | if (mask & UPF_HARD_FLOW) |
663 | uart_set_mctrl(port, TIOCM_RTS); | 660 | uart_set_mctrl(port, TIOCM_RTS); |
@@ -892,10 +889,11 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
892 | */ | 889 | */ |
893 | if (uport->flags & UPF_SPD_MASK) { | 890 | if (uport->flags & UPF_SPD_MASK) { |
894 | char buf[64]; | 891 | char buf[64]; |
895 | printk(KERN_NOTICE | 892 | |
896 | "%s sets custom speed on %s. This " | 893 | dev_notice(uport->dev, |
897 | "is deprecated.\n", current->comm, | 894 | "%s sets custom speed on %s. This is deprecated.\n", |
898 | tty_name(port->tty, buf)); | 895 | current->comm, |
896 | tty_name(port->tty, buf)); | ||
899 | } | 897 | } |
900 | uart_change_speed(tty, state, NULL); | 898 | uart_change_speed(tty, state, NULL); |
901 | } | 899 | } |
@@ -952,7 +950,7 @@ static int uart_get_lsr_info(struct tty_struct *tty, | |||
952 | */ | 950 | */ |
953 | if (uport->x_char || | 951 | if (uport->x_char || |
954 | ((uart_circ_chars_pending(&state->xmit) > 0) && | 952 | ((uart_circ_chars_pending(&state->xmit) > 0) && |
955 | !tty->stopped && !tty->hw_stopped)) | 953 | !uart_tx_stopped(uport))) |
956 | result &= ~TIOCSER_TEMT; | 954 | result &= ~TIOCSER_TEMT; |
957 | 955 | ||
958 | return put_user(result, value); | 956 | return put_user(result, value); |
@@ -1251,7 +1249,6 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1251 | { | 1249 | { |
1252 | struct uart_state *state = tty->driver_data; | 1250 | struct uart_state *state = tty->driver_data; |
1253 | struct uart_port *uport = state->uart_port; | 1251 | struct uart_port *uport = state->uart_port; |
1254 | unsigned long flags; | ||
1255 | unsigned int cflag = tty->termios.c_cflag; | 1252 | unsigned int cflag = tty->termios.c_cflag; |
1256 | unsigned int iflag_mask = IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK; | 1253 | unsigned int iflag_mask = IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK; |
1257 | bool sw_changed = false; | 1254 | bool sw_changed = false; |
@@ -1291,34 +1288,33 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1291 | /* Handle transition away from B0 status */ | 1288 | /* Handle transition away from B0 status */ |
1292 | else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { | 1289 | else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { |
1293 | unsigned int mask = TIOCM_DTR; | 1290 | unsigned int mask = TIOCM_DTR; |
1294 | if (!(cflag & CRTSCTS) || | 1291 | if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) |
1295 | !test_bit(TTY_THROTTLED, &tty->flags)) | ||
1296 | mask |= TIOCM_RTS; | 1292 | mask |= TIOCM_RTS; |
1297 | uart_set_mctrl(uport, mask); | 1293 | uart_set_mctrl(uport, mask); |
1298 | } | 1294 | } |
1299 | 1295 | ||
1300 | /* | 1296 | /* |
1301 | * If the port is doing h/w assisted flow control, do nothing. | 1297 | * If the port is doing h/w assisted flow control, do nothing. |
1302 | * We assume that tty->hw_stopped has never been set. | 1298 | * We assume that port->hw_stopped has never been set. |
1303 | */ | 1299 | */ |
1304 | if (uport->flags & UPF_HARD_FLOW) | 1300 | if (uport->flags & UPF_HARD_FLOW) |
1305 | return; | 1301 | return; |
1306 | 1302 | ||
1307 | /* Handle turning off CRTSCTS */ | 1303 | /* Handle turning off CRTSCTS */ |
1308 | if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { | 1304 | if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { |
1309 | spin_lock_irqsave(&uport->lock, flags); | 1305 | spin_lock_irq(&uport->lock); |
1310 | tty->hw_stopped = 0; | 1306 | uport->hw_stopped = 0; |
1311 | __uart_start(tty); | 1307 | __uart_start(tty); |
1312 | spin_unlock_irqrestore(&uport->lock, flags); | 1308 | spin_unlock_irq(&uport->lock); |
1313 | } | 1309 | } |
1314 | /* Handle turning on CRTSCTS */ | 1310 | /* Handle turning on CRTSCTS */ |
1315 | else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { | 1311 | else if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { |
1316 | spin_lock_irqsave(&uport->lock, flags); | 1312 | spin_lock_irq(&uport->lock); |
1317 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) { | 1313 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) { |
1318 | tty->hw_stopped = 1; | 1314 | uport->hw_stopped = 1; |
1319 | uport->ops->stop_tx(uport); | 1315 | uport->ops->stop_tx(uport); |
1320 | } | 1316 | } |
1321 | spin_unlock_irqrestore(&uport->lock, flags); | 1317 | spin_unlock_irq(&uport->lock); |
1322 | } | 1318 | } |
1323 | } | 1319 | } |
1324 | 1320 | ||
@@ -1975,12 +1971,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
1975 | for (tries = 3; !ops->tx_empty(uport) && tries; tries--) | 1971 | for (tries = 3; !ops->tx_empty(uport) && tries; tries--) |
1976 | msleep(10); | 1972 | msleep(10); |
1977 | if (!tries) | 1973 | if (!tries) |
1978 | printk(KERN_ERR "%s%s%s%d: Unable to drain " | 1974 | dev_err(uport->dev, "%s%d: Unable to drain transmitter\n", |
1979 | "transmitter\n", | 1975 | drv->dev_name, |
1980 | uport->dev ? dev_name(uport->dev) : "", | 1976 | drv->tty_driver->name_base + uport->line); |
1981 | uport->dev ? ": " : "", | ||
1982 | drv->dev_name, | ||
1983 | drv->tty_driver->name_base + uport->line); | ||
1984 | 1977 | ||
1985 | if (console_suspend_enabled || !uart_console(uport)) | 1978 | if (console_suspend_enabled || !uart_console(uport)) |
1986 | ops->shutdown(uport); | 1979 | ops->shutdown(uport); |
@@ -2109,9 +2102,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) | |||
2109 | break; | 2102 | break; |
2110 | } | 2103 | } |
2111 | 2104 | ||
2112 | printk(KERN_INFO "%s%s%s%d at %s (irq = %d, base_baud = %d) is a %s\n", | 2105 | dev_info(port->dev, "%s%d at %s (irq = %d, base_baud = %d) is a %s\n", |
2113 | port->dev ? dev_name(port->dev) : "", | ||
2114 | port->dev ? ": " : "", | ||
2115 | drv->dev_name, | 2106 | drv->dev_name, |
2116 | drv->tty_driver->name_base + port->line, | 2107 | drv->tty_driver->name_base + port->line, |
2117 | address, port->irq, port->uartclk / 16, uart_type(port)); | 2108 | address, port->irq, port->uartclk / 16, uart_type(port)); |
@@ -2640,7 +2631,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2640 | if (likely(!IS_ERR(tty_dev))) { | 2631 | if (likely(!IS_ERR(tty_dev))) { |
2641 | device_set_wakeup_capable(tty_dev, 1); | 2632 | device_set_wakeup_capable(tty_dev, 1); |
2642 | } else { | 2633 | } else { |
2643 | printk(KERN_ERR "Cannot register tty device on line %d\n", | 2634 | dev_err(uport->dev, "Cannot register tty device on line %d\n", |
2644 | uport->line); | 2635 | uport->line); |
2645 | } | 2636 | } |
2646 | 2637 | ||
@@ -2675,7 +2666,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2675 | BUG_ON(in_interrupt()); | 2666 | BUG_ON(in_interrupt()); |
2676 | 2667 | ||
2677 | if (state->uart_port != uport) | 2668 | if (state->uart_port != uport) |
2678 | printk(KERN_ALERT "Removing wrong port: %p != %p\n", | 2669 | dev_alert(uport->dev, "Removing wrong port: %p != %p\n", |
2679 | state->uart_port, uport); | 2670 | state->uart_port, uport); |
2680 | 2671 | ||
2681 | mutex_lock(&port_mutex); | 2672 | mutex_lock(&port_mutex); |
@@ -2757,22 +2748,29 @@ EXPORT_SYMBOL(uart_match_port); | |||
2757 | * uart_handle_dcd_change - handle a change of carrier detect state | 2748 | * uart_handle_dcd_change - handle a change of carrier detect state |
2758 | * @uport: uart_port structure for the open port | 2749 | * @uport: uart_port structure for the open port |
2759 | * @status: new carrier detect status, nonzero if active | 2750 | * @status: new carrier detect status, nonzero if active |
2751 | * | ||
2752 | * Caller must hold uport->lock | ||
2760 | */ | 2753 | */ |
2761 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | 2754 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) |
2762 | { | 2755 | { |
2763 | struct tty_port *port = &uport->state->port; | 2756 | struct tty_port *port = &uport->state->port; |
2764 | struct tty_struct *tty = port->tty; | 2757 | struct tty_struct *tty = port->tty; |
2765 | struct tty_ldisc *ld = tty ? tty_ldisc_ref(tty) : NULL; | 2758 | struct tty_ldisc *ld; |
2766 | 2759 | ||
2767 | if (ld) { | 2760 | lockdep_assert_held_once(&uport->lock); |
2768 | if (ld->ops->dcd_change) | 2761 | |
2769 | ld->ops->dcd_change(tty, status); | 2762 | if (tty) { |
2770 | tty_ldisc_deref(ld); | 2763 | ld = tty_ldisc_ref(tty); |
2764 | if (ld) { | ||
2765 | if (ld->ops->dcd_change) | ||
2766 | ld->ops->dcd_change(tty, status); | ||
2767 | tty_ldisc_deref(ld); | ||
2768 | } | ||
2771 | } | 2769 | } |
2772 | 2770 | ||
2773 | uport->icount.dcd++; | 2771 | uport->icount.dcd++; |
2774 | 2772 | ||
2775 | if (port->flags & ASYNC_CHECK_CD) { | 2773 | if (uart_dcd_enabled(uport)) { |
2776 | if (status) | 2774 | if (status) |
2777 | wake_up_interruptible(&port->open_wait); | 2775 | wake_up_interruptible(&port->open_wait); |
2778 | else if (tty) | 2776 | else if (tty) |
@@ -2785,26 +2783,25 @@ EXPORT_SYMBOL_GPL(uart_handle_dcd_change); | |||
2785 | * uart_handle_cts_change - handle a change of clear-to-send state | 2783 | * uart_handle_cts_change - handle a change of clear-to-send state |
2786 | * @uport: uart_port structure for the open port | 2784 | * @uport: uart_port structure for the open port |
2787 | * @status: new clear to send status, nonzero if active | 2785 | * @status: new clear to send status, nonzero if active |
2786 | * | ||
2787 | * Caller must hold uport->lock | ||
2788 | */ | 2788 | */ |
2789 | void uart_handle_cts_change(struct uart_port *uport, unsigned int status) | 2789 | void uart_handle_cts_change(struct uart_port *uport, unsigned int status) |
2790 | { | 2790 | { |
2791 | struct tty_port *port = &uport->state->port; | 2791 | lockdep_assert_held_once(&uport->lock); |
2792 | struct tty_struct *tty = port->tty; | ||
2793 | 2792 | ||
2794 | uport->icount.cts++; | 2793 | uport->icount.cts++; |
2795 | 2794 | ||
2796 | /* skip below code if the hw flow control is supported */ | 2795 | if (uart_cts_enabled(uport)) { |
2797 | if (tty_port_cts_enabled(port) && | 2796 | if (uport->hw_stopped) { |
2798 | !(uport->flags & UPF_HARD_FLOW)) { | ||
2799 | if (tty->hw_stopped) { | ||
2800 | if (status) { | 2797 | if (status) { |
2801 | tty->hw_stopped = 0; | 2798 | uport->hw_stopped = 0; |
2802 | uport->ops->start_tx(uport); | 2799 | uport->ops->start_tx(uport); |
2803 | uart_write_wakeup(uport); | 2800 | uart_write_wakeup(uport); |
2804 | } | 2801 | } |
2805 | } else { | 2802 | } else { |
2806 | if (!status) { | 2803 | if (!status) { |
2807 | tty->hw_stopped = 1; | 2804 | uport->hw_stopped = 1; |
2808 | uport->ops->stop_tx(uport); | 2805 | uport->ops->stop_tx(uport); |
2809 | } | 2806 | } |
2810 | } | 2807 | } |
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index bf9560ffe3f4..a3035f997b98 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
20 | #include <linux/gpio/consumer.h> | 20 | #include <linux/gpio/consumer.h> |
21 | #include <uapi/asm-generic/termios.h> | 21 | #include <linux/termios.h> |
22 | 22 | ||
23 | #include "serial_mctrl_gpio.h" | 23 | #include "serial_mctrl_gpio.h" |
24 | 24 | ||
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 8b2d7356611d..a3165842ca29 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c | |||
@@ -151,12 +151,20 @@ static inline struct asc_port *to_asc_port(struct uart_port *port) | |||
151 | 151 | ||
152 | static inline u32 asc_in(struct uart_port *port, u32 offset) | 152 | static inline u32 asc_in(struct uart_port *port, u32 offset) |
153 | { | 153 | { |
154 | #ifdef readl_relaxed | ||
155 | return readl_relaxed(port->membase + offset); | ||
156 | #else | ||
154 | return readl(port->membase + offset); | 157 | return readl(port->membase + offset); |
158 | #endif | ||
155 | } | 159 | } |
156 | 160 | ||
157 | static inline void asc_out(struct uart_port *port, u32 offset, u32 value) | 161 | static inline void asc_out(struct uart_port *port, u32 offset, u32 value) |
158 | { | 162 | { |
163 | #ifdef writel_relaxed | ||
164 | writel_relaxed(value, port->membase + offset); | ||
165 | #else | ||
159 | writel(value, port->membase + offset); | 166 | writel(value, port->membase + offset); |
167 | #endif | ||
160 | } | 168 | } |
161 | 169 | ||
162 | /* | 170 | /* |
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 20521db2189f..25d43ce8b318 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c | |||
@@ -268,6 +268,9 @@ static void sunhv_send_xchar(struct uart_port *port, char ch) | |||
268 | unsigned long flags; | 268 | unsigned long flags; |
269 | int limit = 10000; | 269 | int limit = 10000; |
270 | 270 | ||
271 | if (ch == __DISABLED_CHAR) | ||
272 | return; | ||
273 | |||
271 | spin_lock_irqsave(&port->lock, flags); | 274 | spin_lock_irqsave(&port->lock, flags); |
272 | 275 | ||
273 | while (limit-- > 0) { | 276 | while (limit-- > 0) { |
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index b9598b227a45..b339fe4811cd 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c | |||
@@ -436,7 +436,7 @@ static void sunsab_start_tx(struct uart_port *port) | |||
436 | struct circ_buf *xmit = &up->port.state->xmit; | 436 | struct circ_buf *xmit = &up->port.state->xmit; |
437 | int i; | 437 | int i; |
438 | 438 | ||
439 | if (uart_circ_empty(xmit)) | 439 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
440 | return; | 440 | return; |
441 | 441 | ||
442 | up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR); | 442 | up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR); |
@@ -468,6 +468,9 @@ static void sunsab_send_xchar(struct uart_port *port, char ch) | |||
468 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | 468 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; |
469 | unsigned long flags; | 469 | unsigned long flags; |
470 | 470 | ||
471 | if (ch == __DISABLED_CHAR) | ||
472 | return; | ||
473 | |||
471 | spin_lock_irqsave(&up->port.lock, flags); | 474 | spin_lock_irqsave(&up->port.lock, flags); |
472 | 475 | ||
473 | sunsab_tec_wait(up); | 476 | sunsab_tec_wait(up); |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 9fc22f40796e..189f52e3111f 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -665,7 +665,6 @@ static struct platform_driver ulite_platform_driver = { | |||
665 | .probe = ulite_probe, | 665 | .probe = ulite_probe, |
666 | .remove = ulite_remove, | 666 | .remove = ulite_remove, |
667 | .driver = { | 667 | .driver = { |
668 | .owner = THIS_MODULE, | ||
669 | .name = "uartlite", | 668 | .name = "uartlite", |
670 | .of_match_table = of_match_ptr(ulite_of_match), | 669 | .of_match_table = of_match_ptr(ulite_of_match), |
671 | }, | 670 | }, |
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index db0c8a4ab03e..d7f9d622cdcb 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c | |||
@@ -847,7 +847,6 @@ void __init vr41xx_siu_early_setup(struct uart_port *port) | |||
847 | siu_uart_ports[port->line].type = port->type; | 847 | siu_uart_ports[port->line].type = port->type; |
848 | siu_uart_ports[port->line].uartclk = SIU_BAUD_BASE * 16; | 848 | siu_uart_ports[port->line].uartclk = SIU_BAUD_BASE * 16; |
849 | siu_uart_ports[port->line].mapbase = port->mapbase; | 849 | siu_uart_ports[port->line].mapbase = port->mapbase; |
850 | siu_uart_ports[port->line].mapbase = port->mapbase; | ||
851 | siu_uart_ports[port->line].ops = &siu_uart_ops; | 850 | siu_uart_ports[port->line].ops = &siu_uart_ops; |
852 | } | 851 | } |
853 | 852 | ||
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 15ad6fcda88b..b2bc9e8ba048 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
@@ -33,8 +33,8 @@ | |||
33 | #include <linux/serial.h> | 33 | #include <linux/serial.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/of.h> | 36 | #include <linux/of.h> |
37 | #include <linux/of_device.h> | ||
38 | #include <linux/err.h> | 38 | #include <linux/err.h> |
39 | 39 | ||
40 | /* | 40 | /* |
@@ -78,13 +78,40 @@ | |||
78 | #define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT) | 78 | #define RX_FIFO_INTS (RXFAF | RXFF | RXOVER | PER | FER | RXTOUT) |
79 | #define TX_FIFO_INTS (TXFAE | TXFE | TXUDR) | 79 | #define TX_FIFO_INTS (TXFAE | TXFE | TXUDR) |
80 | 80 | ||
81 | /* | ||
82 | * Line control bits | ||
83 | */ | ||
84 | |||
85 | #define VT8500_TXEN (1 << 0) /* Enable transmit logic */ | ||
86 | #define VT8500_RXEN (1 << 1) /* Enable receive logic */ | ||
87 | #define VT8500_CS8 (1 << 2) /* 8-bit data length (vs. 7-bit) */ | ||
88 | #define VT8500_CSTOPB (1 << 3) /* 2 stop bits (vs. 1) */ | ||
89 | #define VT8500_PARENB (1 << 4) /* Enable parity */ | ||
90 | #define VT8500_PARODD (1 << 5) /* Odd parity (vs. even) */ | ||
91 | #define VT8500_RTS (1 << 6) /* Ready to send */ | ||
92 | #define VT8500_LOOPBK (1 << 7) /* Enable internal loopback */ | ||
93 | #define VT8500_DMA (1 << 8) /* Enable DMA mode (needs FIFO) */ | ||
94 | #define VT8500_BREAK (1 << 9) /* Initiate break signal */ | ||
95 | #define VT8500_PSLVERR (1 << 10) /* APB error upon empty RX FIFO read */ | ||
96 | #define VT8500_SWRTSCTS (1 << 11) /* Software-controlled RTS/CTS */ | ||
97 | |||
98 | /* | ||
99 | * Capability flags (driver-internal) | ||
100 | */ | ||
101 | |||
102 | #define VT8500_HAS_SWRTSCTS_SWITCH (1 << 1) | ||
103 | |||
104 | #define VT8500_RECOMMENDED_CLK 12000000 | ||
105 | #define VT8500_OVERSAMPLING_DIVISOR 13 | ||
81 | #define VT8500_MAX_PORTS 6 | 106 | #define VT8500_MAX_PORTS 6 |
82 | 107 | ||
83 | struct vt8500_port { | 108 | struct vt8500_port { |
84 | struct uart_port uart; | 109 | struct uart_port uart; |
85 | char name[16]; | 110 | char name[16]; |
86 | struct clk *clk; | 111 | struct clk *clk; |
112 | unsigned int clk_predivisor; | ||
87 | unsigned int ier; | 113 | unsigned int ier; |
114 | unsigned int vt8500_uart_flags; | ||
88 | }; | 115 | }; |
89 | 116 | ||
90 | /* | 117 | /* |
@@ -267,31 +294,45 @@ static unsigned int vt8500_get_mctrl(struct uart_port *port) | |||
267 | 294 | ||
268 | static void vt8500_set_mctrl(struct uart_port *port, unsigned int mctrl) | 295 | static void vt8500_set_mctrl(struct uart_port *port, unsigned int mctrl) |
269 | { | 296 | { |
297 | unsigned int lcr = vt8500_read(port, VT8500_URLCR); | ||
298 | |||
299 | if (mctrl & TIOCM_RTS) | ||
300 | lcr |= VT8500_RTS; | ||
301 | else | ||
302 | lcr &= ~VT8500_RTS; | ||
303 | |||
304 | vt8500_write(port, lcr, VT8500_URLCR); | ||
270 | } | 305 | } |
271 | 306 | ||
272 | static void vt8500_break_ctl(struct uart_port *port, int break_ctl) | 307 | static void vt8500_break_ctl(struct uart_port *port, int break_ctl) |
273 | { | 308 | { |
274 | if (break_ctl) | 309 | if (break_ctl) |
275 | vt8500_write(port, vt8500_read(port, VT8500_URLCR) | (1 << 9), | 310 | vt8500_write(port, |
311 | vt8500_read(port, VT8500_URLCR) | VT8500_BREAK, | ||
276 | VT8500_URLCR); | 312 | VT8500_URLCR); |
277 | } | 313 | } |
278 | 314 | ||
279 | static int vt8500_set_baud_rate(struct uart_port *port, unsigned int baud) | 315 | static int vt8500_set_baud_rate(struct uart_port *port, unsigned int baud) |
280 | { | 316 | { |
317 | struct vt8500_port *vt8500_port = | ||
318 | container_of(port, struct vt8500_port, uart); | ||
281 | unsigned long div; | 319 | unsigned long div; |
282 | unsigned int loops = 1000; | 320 | unsigned int loops = 1000; |
283 | 321 | ||
284 | div = vt8500_read(port, VT8500_URDIV) & ~(0x3ff); | 322 | div = ((vt8500_port->clk_predivisor - 1) & 0xf) << 16; |
323 | div |= (uart_get_divisor(port, baud) - 1) & 0x3ff; | ||
285 | 324 | ||
286 | if (unlikely((baud < 900) || (baud > 921600))) | 325 | /* Effective baud rate */ |
287 | div |= 7; | 326 | baud = port->uartclk / 16 / ((div & 0x3ff) + 1); |
288 | else | ||
289 | div |= (921600 / baud) - 1; | ||
290 | 327 | ||
291 | while ((vt8500_read(port, VT8500_URUSR) & (1 << 5)) && --loops) | 328 | while ((vt8500_read(port, VT8500_URUSR) & (1 << 5)) && --loops) |
292 | cpu_relax(); | 329 | cpu_relax(); |
330 | |||
293 | vt8500_write(port, div, VT8500_URDIV); | 331 | vt8500_write(port, div, VT8500_URDIV); |
294 | 332 | ||
333 | /* Break signal timing depends on baud rate, update accordingly */ | ||
334 | vt8500_write(port, mult_frac(baud, 4096, 1000000), VT8500_URBKR); | ||
335 | |||
295 | return baud; | 336 | return baud; |
296 | } | 337 | } |
297 | 338 | ||
@@ -347,31 +388,35 @@ static void vt8500_set_termios(struct uart_port *port, | |||
347 | 388 | ||
348 | /* calculate parity */ | 389 | /* calculate parity */ |
349 | lcr = vt8500_read(&vt8500_port->uart, VT8500_URLCR); | 390 | lcr = vt8500_read(&vt8500_port->uart, VT8500_URLCR); |
350 | lcr &= ~((1 << 5) | (1 << 4)); | 391 | lcr &= ~(VT8500_PARENB | VT8500_PARODD); |
351 | if (termios->c_cflag & PARENB) { | 392 | if (termios->c_cflag & PARENB) { |
352 | lcr |= (1 << 4); | 393 | lcr |= VT8500_PARENB; |
353 | termios->c_cflag &= ~CMSPAR; | 394 | termios->c_cflag &= ~CMSPAR; |
354 | if (termios->c_cflag & PARODD) | 395 | if (termios->c_cflag & PARODD) |
355 | lcr |= (1 << 5); | 396 | lcr |= VT8500_PARODD; |
356 | } | 397 | } |
357 | 398 | ||
358 | /* calculate bits per char */ | 399 | /* calculate bits per char */ |
359 | lcr &= ~(1 << 2); | 400 | lcr &= ~VT8500_CS8; |
360 | switch (termios->c_cflag & CSIZE) { | 401 | switch (termios->c_cflag & CSIZE) { |
361 | case CS7: | 402 | case CS7: |
362 | break; | 403 | break; |
363 | case CS8: | 404 | case CS8: |
364 | default: | 405 | default: |
365 | lcr |= (1 << 2); | 406 | lcr |= VT8500_CS8; |
366 | termios->c_cflag &= ~CSIZE; | 407 | termios->c_cflag &= ~CSIZE; |
367 | termios->c_cflag |= CS8; | 408 | termios->c_cflag |= CS8; |
368 | break; | 409 | break; |
369 | } | 410 | } |
370 | 411 | ||
371 | /* calculate stop bits */ | 412 | /* calculate stop bits */ |
372 | lcr &= ~(1 << 3); | 413 | lcr &= ~VT8500_CSTOPB; |
373 | if (termios->c_cflag & CSTOPB) | 414 | if (termios->c_cflag & CSTOPB) |
374 | lcr |= (1 << 3); | 415 | lcr |= VT8500_CSTOPB; |
416 | |||
417 | lcr &= ~VT8500_SWRTSCTS; | ||
418 | if (vt8500_port->vt8500_uart_flags & VT8500_HAS_SWRTSCTS_SWITCH) | ||
419 | lcr |= VT8500_SWRTSCTS; | ||
375 | 420 | ||
376 | /* set parity, bits per char, and stop bit */ | 421 | /* set parity, bits per char, and stop bit */ |
377 | vt8500_write(&vt8500_port->uart, lcr, VT8500_URLCR); | 422 | vt8500_write(&vt8500_port->uart, lcr, VT8500_URLCR); |
@@ -521,6 +566,33 @@ static struct console vt8500_console = { | |||
521 | #define VT8500_CONSOLE NULL | 566 | #define VT8500_CONSOLE NULL |
522 | #endif | 567 | #endif |
523 | 568 | ||
569 | #ifdef CONFIG_CONSOLE_POLL | ||
570 | static int vt8500_get_poll_char(struct uart_port *port) | ||
571 | { | ||
572 | unsigned int status = vt8500_read(port, VT8500_URFIDX); | ||
573 | |||
574 | if (!(status & 0x1f00)) | ||
575 | return NO_POLL_CHAR; | ||
576 | |||
577 | return vt8500_read(port, VT8500_RXFIFO) & 0xff; | ||
578 | } | ||
579 | |||
580 | static void vt8500_put_poll_char(struct uart_port *port, unsigned char c) | ||
581 | { | ||
582 | unsigned int status, tmout = 10000; | ||
583 | |||
584 | do { | ||
585 | status = vt8500_read(port, VT8500_URFIDX); | ||
586 | |||
587 | if (--tmout == 0) | ||
588 | break; | ||
589 | udelay(1); | ||
590 | } while (status & 0x10); | ||
591 | |||
592 | vt8500_write(port, c, VT8500_TXFIFO); | ||
593 | } | ||
594 | #endif | ||
595 | |||
524 | static struct uart_ops vt8500_uart_pops = { | 596 | static struct uart_ops vt8500_uart_pops = { |
525 | .tx_empty = vt8500_tx_empty, | 597 | .tx_empty = vt8500_tx_empty, |
526 | .set_mctrl = vt8500_set_mctrl, | 598 | .set_mctrl = vt8500_set_mctrl, |
@@ -538,6 +610,10 @@ static struct uart_ops vt8500_uart_pops = { | |||
538 | .request_port = vt8500_request_port, | 610 | .request_port = vt8500_request_port, |
539 | .config_port = vt8500_config_port, | 611 | .config_port = vt8500_config_port, |
540 | .verify_port = vt8500_verify_port, | 612 | .verify_port = vt8500_verify_port, |
613 | #ifdef CONFIG_CONSOLE_POLL | ||
614 | .poll_get_char = vt8500_get_poll_char, | ||
615 | .poll_put_char = vt8500_put_poll_char, | ||
616 | #endif | ||
541 | }; | 617 | }; |
542 | 618 | ||
543 | static struct uart_driver vt8500_uart_driver = { | 619 | static struct uart_driver vt8500_uart_driver = { |
@@ -548,14 +624,31 @@ static struct uart_driver vt8500_uart_driver = { | |||
548 | .cons = VT8500_CONSOLE, | 624 | .cons = VT8500_CONSOLE, |
549 | }; | 625 | }; |
550 | 626 | ||
627 | static unsigned int vt8500_flags; /* none required so far */ | ||
628 | static unsigned int wm8880_flags = VT8500_HAS_SWRTSCTS_SWITCH; | ||
629 | |||
630 | static const struct of_device_id wmt_dt_ids[] = { | ||
631 | { .compatible = "via,vt8500-uart", .data = &vt8500_flags}, | ||
632 | { .compatible = "wm,wm8880-uart", .data = &wm8880_flags}, | ||
633 | {} | ||
634 | }; | ||
635 | |||
551 | static int vt8500_serial_probe(struct platform_device *pdev) | 636 | static int vt8500_serial_probe(struct platform_device *pdev) |
552 | { | 637 | { |
553 | struct vt8500_port *vt8500_port; | 638 | struct vt8500_port *vt8500_port; |
554 | struct resource *mmres, *irqres; | 639 | struct resource *mmres, *irqres; |
555 | struct device_node *np = pdev->dev.of_node; | 640 | struct device_node *np = pdev->dev.of_node; |
641 | const struct of_device_id *match; | ||
642 | const unsigned int *flags; | ||
556 | int ret; | 643 | int ret; |
557 | int port; | 644 | int port; |
558 | 645 | ||
646 | match = of_match_device(wmt_dt_ids, &pdev->dev); | ||
647 | if (!match) | ||
648 | return -EINVAL; | ||
649 | |||
650 | flags = match->data; | ||
651 | |||
559 | mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 652 | mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
560 | irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 653 | irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
561 | if (!mmres || !irqres) | 654 | if (!mmres || !irqres) |
@@ -605,6 +698,11 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
605 | return ret; | 698 | return ret; |
606 | } | 699 | } |
607 | 700 | ||
701 | vt8500_port->vt8500_uart_flags = *flags; | ||
702 | vt8500_port->clk_predivisor = DIV_ROUND_CLOSEST( | ||
703 | clk_get_rate(vt8500_port->clk), | ||
704 | VT8500_RECOMMENDED_CLK | ||
705 | ); | ||
608 | vt8500_port->uart.type = PORT_VT8500; | 706 | vt8500_port->uart.type = PORT_VT8500; |
609 | vt8500_port->uart.iotype = UPIO_MEM; | 707 | vt8500_port->uart.iotype = UPIO_MEM; |
610 | vt8500_port->uart.mapbase = mmres->start; | 708 | vt8500_port->uart.mapbase = mmres->start; |
@@ -615,7 +713,10 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
615 | vt8500_port->uart.dev = &pdev->dev; | 713 | vt8500_port->uart.dev = &pdev->dev; |
616 | vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; | 714 | vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; |
617 | 715 | ||
618 | vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk); | 716 | /* Serial core uses the magic "16" everywhere - adjust for it */ |
717 | vt8500_port->uart.uartclk = 16 * clk_get_rate(vt8500_port->clk) / | ||
718 | vt8500_port->clk_predivisor / | ||
719 | VT8500_OVERSAMPLING_DIVISOR; | ||
619 | 720 | ||
620 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), | 721 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), |
621 | "VT8500 UART%d", pdev->id); | 722 | "VT8500 UART%d", pdev->id); |
@@ -639,11 +740,6 @@ static int vt8500_serial_remove(struct platform_device *pdev) | |||
639 | return 0; | 740 | return 0; |
640 | } | 741 | } |
641 | 742 | ||
642 | static const struct of_device_id wmt_dt_ids[] = { | ||
643 | { .compatible = "via,vt8500-uart", }, | ||
644 | {} | ||
645 | }; | ||
646 | |||
647 | static struct platform_driver vt8500_platform_driver = { | 743 | static struct platform_driver vt8500_platform_driver = { |
648 | .probe = vt8500_serial_probe, | 744 | .probe = vt8500_serial_probe, |
649 | .remove = vt8500_serial_remove, | 745 | .remove = vt8500_serial_remove, |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 806e4bcadbd7..200c1af2141b 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -1051,6 +1051,25 @@ static void cdns_uart_console_putchar(struct uart_port *port, int ch) | |||
1051 | cdns_uart_writel(ch, CDNS_UART_FIFO_OFFSET); | 1051 | cdns_uart_writel(ch, CDNS_UART_FIFO_OFFSET); |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | static void cdns_early_write(struct console *con, const char *s, unsigned n) | ||
1055 | { | ||
1056 | struct earlycon_device *dev = con->data; | ||
1057 | |||
1058 | uart_console_write(&dev->port, s, n, cdns_uart_console_putchar); | ||
1059 | } | ||
1060 | |||
1061 | static int __init cdns_early_console_setup(struct earlycon_device *device, | ||
1062 | const char *opt) | ||
1063 | { | ||
1064 | if (!device->port.membase) | ||
1065 | return -ENODEV; | ||
1066 | |||
1067 | device->con->write = cdns_early_write; | ||
1068 | |||
1069 | return 0; | ||
1070 | } | ||
1071 | EARLYCON_DECLARE(cdns, cdns_early_console_setup); | ||
1072 | |||
1054 | /** | 1073 | /** |
1055 | * cdns_uart_console_write - perform write operation | 1074 | * cdns_uart_console_write - perform write operation |
1056 | * @co: Console handle | 1075 | * @co: Console handle |
@@ -1428,7 +1447,6 @@ static struct platform_driver cdns_uart_platform_driver = { | |||
1428 | .probe = cdns_uart_probe, | 1447 | .probe = cdns_uart_probe, |
1429 | .remove = cdns_uart_remove, | 1448 | .remove = cdns_uart_remove, |
1430 | .driver = { | 1449 | .driver = { |
1431 | .owner = THIS_MODULE, | ||
1432 | .name = CDNS_UART_NAME, | 1450 | .name = CDNS_UART_NAME, |
1433 | .of_match_table = cdns_uart_of_match, | 1451 | .of_match_table = cdns_uart_of_match, |
1434 | .pm = &cdns_uart_dev_pm_ops, | 1452 | .pm = &cdns_uart_dev_pm_ops, |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 8fbad3410c75..2f6f9b5e4891 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -908,8 +908,7 @@ void no_tty(void) | |||
908 | * stop_tty - propagate flow control | 908 | * stop_tty - propagate flow control |
909 | * @tty: tty to stop | 909 | * @tty: tty to stop |
910 | * | 910 | * |
911 | * Perform flow control to the driver. For PTY/TTY pairs we | 911 | * Perform flow control to the driver. May be called |
912 | * must also propagate the TIOCKPKT status. May be called | ||
913 | * on an already stopped device and will not re-call the driver | 912 | * on an already stopped device and will not re-call the driver |
914 | * method. | 913 | * method. |
915 | * | 914 | * |
@@ -919,64 +918,58 @@ void no_tty(void) | |||
919 | * but not always. | 918 | * but not always. |
920 | * | 919 | * |
921 | * Locking: | 920 | * Locking: |
922 | * Uses the tty control lock internally | 921 | * flow_lock |
923 | */ | 922 | */ |
924 | 923 | ||
925 | void stop_tty(struct tty_struct *tty) | 924 | void __stop_tty(struct tty_struct *tty) |
926 | { | 925 | { |
927 | unsigned long flags; | 926 | if (tty->stopped) |
928 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
929 | if (tty->stopped) { | ||
930 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
931 | return; | 927 | return; |
932 | } | ||
933 | tty->stopped = 1; | 928 | tty->stopped = 1; |
934 | if (tty->link && tty->link->packet) { | ||
935 | tty->ctrl_status &= ~TIOCPKT_START; | ||
936 | tty->ctrl_status |= TIOCPKT_STOP; | ||
937 | wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); | ||
938 | } | ||
939 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
940 | if (tty->ops->stop) | 929 | if (tty->ops->stop) |
941 | (tty->ops->stop)(tty); | 930 | (tty->ops->stop)(tty); |
942 | } | 931 | } |
943 | 932 | ||
933 | void stop_tty(struct tty_struct *tty) | ||
934 | { | ||
935 | unsigned long flags; | ||
936 | |||
937 | spin_lock_irqsave(&tty->flow_lock, flags); | ||
938 | __stop_tty(tty); | ||
939 | spin_unlock_irqrestore(&tty->flow_lock, flags); | ||
940 | } | ||
944 | EXPORT_SYMBOL(stop_tty); | 941 | EXPORT_SYMBOL(stop_tty); |
945 | 942 | ||
946 | /** | 943 | /** |
947 | * start_tty - propagate flow control | 944 | * start_tty - propagate flow control |
948 | * @tty: tty to start | 945 | * @tty: tty to start |
949 | * | 946 | * |
950 | * Start a tty that has been stopped if at all possible. Perform | 947 | * Start a tty that has been stopped if at all possible. If this |
951 | * any necessary wakeups and propagate the TIOCPKT status. If this | 948 | * tty was previous stopped and is now being started, the driver |
952 | * is the tty was previous stopped and is being started then the | 949 | * start method is invoked and the line discipline woken. |
953 | * driver start method is invoked and the line discipline woken. | ||
954 | * | 950 | * |
955 | * Locking: | 951 | * Locking: |
956 | * ctrl_lock | 952 | * flow_lock |
957 | */ | 953 | */ |
958 | 954 | ||
959 | void start_tty(struct tty_struct *tty) | 955 | void __start_tty(struct tty_struct *tty) |
960 | { | 956 | { |
961 | unsigned long flags; | 957 | if (!tty->stopped || tty->flow_stopped) |
962 | spin_lock_irqsave(&tty->ctrl_lock, flags); | ||
963 | if (!tty->stopped || tty->flow_stopped) { | ||
964 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
965 | return; | 958 | return; |
966 | } | ||
967 | tty->stopped = 0; | 959 | tty->stopped = 0; |
968 | if (tty->link && tty->link->packet) { | ||
969 | tty->ctrl_status &= ~TIOCPKT_STOP; | ||
970 | tty->ctrl_status |= TIOCPKT_START; | ||
971 | wake_up_interruptible_poll(&tty->link->read_wait, POLLIN); | ||
972 | } | ||
973 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | ||
974 | if (tty->ops->start) | 960 | if (tty->ops->start) |
975 | (tty->ops->start)(tty); | 961 | (tty->ops->start)(tty); |
976 | /* If we have a running line discipline it may need kicking */ | ||
977 | tty_wakeup(tty); | 962 | tty_wakeup(tty); |
978 | } | 963 | } |
979 | 964 | ||
965 | void start_tty(struct tty_struct *tty) | ||
966 | { | ||
967 | unsigned long flags; | ||
968 | |||
969 | spin_lock_irqsave(&tty->flow_lock, flags); | ||
970 | __start_tty(tty); | ||
971 | spin_unlock_irqrestore(&tty->flow_lock, flags); | ||
972 | } | ||
980 | EXPORT_SYMBOL(start_tty); | 973 | EXPORT_SYMBOL(start_tty); |
981 | 974 | ||
982 | /* We limit tty time update visibility to every 8 seconds or so. */ | 975 | /* We limit tty time update visibility to every 8 seconds or so. */ |
@@ -1030,14 +1023,14 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
1030 | return i; | 1023 | return i; |
1031 | } | 1024 | } |
1032 | 1025 | ||
1033 | void tty_write_unlock(struct tty_struct *tty) | 1026 | static void tty_write_unlock(struct tty_struct *tty) |
1034 | __releases(&tty->atomic_write_lock) | 1027 | __releases(&tty->atomic_write_lock) |
1035 | { | 1028 | { |
1036 | mutex_unlock(&tty->atomic_write_lock); | 1029 | mutex_unlock(&tty->atomic_write_lock); |
1037 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); | 1030 | wake_up_interruptible_poll(&tty->write_wait, POLLOUT); |
1038 | } | 1031 | } |
1039 | 1032 | ||
1040 | int tty_write_lock(struct tty_struct *tty, int ndelay) | 1033 | static int tty_write_lock(struct tty_struct *tty, int ndelay) |
1041 | __acquires(&tty->atomic_write_lock) | 1034 | __acquires(&tty->atomic_write_lock) |
1042 | { | 1035 | { |
1043 | if (!mutex_trylock(&tty->atomic_write_lock)) { | 1036 | if (!mutex_trylock(&tty->atomic_write_lock)) { |
@@ -1224,6 +1217,35 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf, | |||
1224 | return tty_write(file, buf, count, ppos); | 1217 | return tty_write(file, buf, count, ppos); |
1225 | } | 1218 | } |
1226 | 1219 | ||
1220 | /** | ||
1221 | * tty_send_xchar - send priority character | ||
1222 | * | ||
1223 | * Send a high priority character to the tty even if stopped | ||
1224 | * | ||
1225 | * Locking: none for xchar method, write ordering for write method. | ||
1226 | */ | ||
1227 | |||
1228 | int tty_send_xchar(struct tty_struct *tty, char ch) | ||
1229 | { | ||
1230 | int was_stopped = tty->stopped; | ||
1231 | |||
1232 | if (tty->ops->send_xchar) { | ||
1233 | tty->ops->send_xchar(tty, ch); | ||
1234 | return 0; | ||
1235 | } | ||
1236 | |||
1237 | if (tty_write_lock(tty, 0) < 0) | ||
1238 | return -ERESTARTSYS; | ||
1239 | |||
1240 | if (was_stopped) | ||
1241 | start_tty(tty); | ||
1242 | tty->ops->write(tty, &ch, 1); | ||
1243 | if (was_stopped) | ||
1244 | stop_tty(tty); | ||
1245 | tty_write_unlock(tty); | ||
1246 | return 0; | ||
1247 | } | ||
1248 | |||
1227 | static char ptychar[] = "pqrstuvwxyzabcde"; | 1249 | static char ptychar[] = "pqrstuvwxyzabcde"; |
1228 | 1250 | ||
1229 | /** | 1251 | /** |
@@ -1544,13 +1566,14 @@ static void release_one_tty(struct work_struct *work) | |||
1544 | struct tty_struct *tty = | 1566 | struct tty_struct *tty = |
1545 | container_of(work, struct tty_struct, hangup_work); | 1567 | container_of(work, struct tty_struct, hangup_work); |
1546 | struct tty_driver *driver = tty->driver; | 1568 | struct tty_driver *driver = tty->driver; |
1569 | struct module *owner = driver->owner; | ||
1547 | 1570 | ||
1548 | if (tty->ops->cleanup) | 1571 | if (tty->ops->cleanup) |
1549 | tty->ops->cleanup(tty); | 1572 | tty->ops->cleanup(tty); |
1550 | 1573 | ||
1551 | tty->magic = 0; | 1574 | tty->magic = 0; |
1552 | tty_driver_kref_put(driver); | 1575 | tty_driver_kref_put(driver); |
1553 | module_put(driver->owner); | 1576 | module_put(owner); |
1554 | 1577 | ||
1555 | spin_lock(&tty_files_lock); | 1578 | spin_lock(&tty_files_lock); |
1556 | list_del_init(&tty->tty_files); | 1579 | list_del_init(&tty->tty_files); |
@@ -3018,6 +3041,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) | |||
3018 | INIT_WORK(&tty->hangup_work, do_tty_hangup); | 3041 | INIT_WORK(&tty->hangup_work, do_tty_hangup); |
3019 | mutex_init(&tty->atomic_write_lock); | 3042 | mutex_init(&tty->atomic_write_lock); |
3020 | spin_lock_init(&tty->ctrl_lock); | 3043 | spin_lock_init(&tty->ctrl_lock); |
3044 | spin_lock_init(&tty->flow_lock); | ||
3021 | INIT_LIST_HEAD(&tty->tty_files); | 3045 | INIT_LIST_HEAD(&tty->tty_files); |
3022 | INIT_WORK(&tty->SAK_work, do_SAK_work); | 3046 | INIT_WORK(&tty->SAK_work, do_SAK_work); |
3023 | 3047 | ||
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 6fd60fece6b4..62380ccf70fb 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -402,7 +402,7 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, | |||
402 | 402 | ||
403 | #ifdef BOTHER | 403 | #ifdef BOTHER |
404 | /* If the user asked for a precise weird speed give a precise weird | 404 | /* If the user asked for a precise weird speed give a precise weird |
405 | answer. If they asked for a Bfoo speed they many have problems | 405 | answer. If they asked for a Bfoo speed they may have problems |
406 | digesting non-exact replies so fuzz a bit */ | 406 | digesting non-exact replies so fuzz a bit */ |
407 | 407 | ||
408 | if ((termios->c_cflag & CBAUD) == BOTHER) | 408 | if ((termios->c_cflag & CBAUD) == BOTHER) |
@@ -912,35 +912,6 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
912 | #endif | 912 | #endif |
913 | 913 | ||
914 | /** | 914 | /** |
915 | * send_prio_char - send priority character | ||
916 | * | ||
917 | * Send a high priority character to the tty even if stopped | ||
918 | * | ||
919 | * Locking: none for xchar method, write ordering for write method. | ||
920 | */ | ||
921 | |||
922 | static int send_prio_char(struct tty_struct *tty, char ch) | ||
923 | { | ||
924 | int was_stopped = tty->stopped; | ||
925 | |||
926 | if (tty->ops->send_xchar) { | ||
927 | tty->ops->send_xchar(tty, ch); | ||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | if (tty_write_lock(tty, 0) < 0) | ||
932 | return -ERESTARTSYS; | ||
933 | |||
934 | if (was_stopped) | ||
935 | start_tty(tty); | ||
936 | tty->ops->write(tty, &ch, 1); | ||
937 | if (was_stopped) | ||
938 | stop_tty(tty); | ||
939 | tty_write_unlock(tty); | ||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | /** | ||
944 | * tty_change_softcar - carrier change ioctl helper | 915 | * tty_change_softcar - carrier change ioctl helper |
945 | * @tty: tty to update | 916 | * @tty: tty to update |
946 | * @arg: enable/disable CLOCAL | 917 | * @arg: enable/disable CLOCAL |
@@ -1177,29 +1148,37 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, | |||
1177 | return retval; | 1148 | return retval; |
1178 | switch (arg) { | 1149 | switch (arg) { |
1179 | case TCOOFF: | 1150 | case TCOOFF: |
1151 | spin_lock_irq(&tty->flow_lock); | ||
1180 | if (!tty->flow_stopped) { | 1152 | if (!tty->flow_stopped) { |
1181 | tty->flow_stopped = 1; | 1153 | tty->flow_stopped = 1; |
1182 | stop_tty(tty); | 1154 | __stop_tty(tty); |
1183 | } | 1155 | } |
1156 | spin_unlock_irq(&tty->flow_lock); | ||
1184 | break; | 1157 | break; |
1185 | case TCOON: | 1158 | case TCOON: |
1159 | spin_lock_irq(&tty->flow_lock); | ||
1186 | if (tty->flow_stopped) { | 1160 | if (tty->flow_stopped) { |
1187 | tty->flow_stopped = 0; | 1161 | tty->flow_stopped = 0; |
1188 | start_tty(tty); | 1162 | __start_tty(tty); |
1189 | } | 1163 | } |
1164 | spin_unlock_irq(&tty->flow_lock); | ||
1190 | break; | 1165 | break; |
1191 | case TCIOFF: | 1166 | case TCIOFF: |
1167 | down_read(&tty->termios_rwsem); | ||
1192 | if (STOP_CHAR(tty) != __DISABLED_CHAR) | 1168 | if (STOP_CHAR(tty) != __DISABLED_CHAR) |
1193 | return send_prio_char(tty, STOP_CHAR(tty)); | 1169 | retval = tty_send_xchar(tty, STOP_CHAR(tty)); |
1170 | up_read(&tty->termios_rwsem); | ||
1194 | break; | 1171 | break; |
1195 | case TCION: | 1172 | case TCION: |
1173 | down_read(&tty->termios_rwsem); | ||
1196 | if (START_CHAR(tty) != __DISABLED_CHAR) | 1174 | if (START_CHAR(tty) != __DISABLED_CHAR) |
1197 | return send_prio_char(tty, START_CHAR(tty)); | 1175 | retval = tty_send_xchar(tty, START_CHAR(tty)); |
1176 | up_read(&tty->termios_rwsem); | ||
1198 | break; | 1177 | break; |
1199 | default: | 1178 | default: |
1200 | return -EINVAL; | 1179 | return -EINVAL; |
1201 | } | 1180 | } |
1202 | return 0; | 1181 | return retval; |
1203 | case TCFLSH: | 1182 | case TCFLSH: |
1204 | retval = tty_check_change(tty); | 1183 | retval = tty_check_change(tty); |
1205 | if (retval) | 1184 | if (retval) |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index d0e3a4497707..c039cfea5b11 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -268,30 +268,30 @@ EXPORT_SYMBOL(kd_mksound); | |||
268 | static int kbd_rate_helper(struct input_handle *handle, void *data) | 268 | static int kbd_rate_helper(struct input_handle *handle, void *data) |
269 | { | 269 | { |
270 | struct input_dev *dev = handle->dev; | 270 | struct input_dev *dev = handle->dev; |
271 | struct kbd_repeat *rep = data; | 271 | struct kbd_repeat *rpt = data; |
272 | 272 | ||
273 | if (test_bit(EV_REP, dev->evbit)) { | 273 | if (test_bit(EV_REP, dev->evbit)) { |
274 | 274 | ||
275 | if (rep[0].delay > 0) | 275 | if (rpt[0].delay > 0) |
276 | input_inject_event(handle, | 276 | input_inject_event(handle, |
277 | EV_REP, REP_DELAY, rep[0].delay); | 277 | EV_REP, REP_DELAY, rpt[0].delay); |
278 | if (rep[0].period > 0) | 278 | if (rpt[0].period > 0) |
279 | input_inject_event(handle, | 279 | input_inject_event(handle, |
280 | EV_REP, REP_PERIOD, rep[0].period); | 280 | EV_REP, REP_PERIOD, rpt[0].period); |
281 | 281 | ||
282 | rep[1].delay = dev->rep[REP_DELAY]; | 282 | rpt[1].delay = dev->rep[REP_DELAY]; |
283 | rep[1].period = dev->rep[REP_PERIOD]; | 283 | rpt[1].period = dev->rep[REP_PERIOD]; |
284 | } | 284 | } |
285 | 285 | ||
286 | return 0; | 286 | return 0; |
287 | } | 287 | } |
288 | 288 | ||
289 | int kbd_rate(struct kbd_repeat *rep) | 289 | int kbd_rate(struct kbd_repeat *rpt) |
290 | { | 290 | { |
291 | struct kbd_repeat data[2] = { *rep }; | 291 | struct kbd_repeat data[2] = { *rpt }; |
292 | 292 | ||
293 | input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper); | 293 | input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper); |
294 | *rep = data[1]; /* Copy currently used settings */ | 294 | *rpt = data[1]; /* Copy currently used settings */ |
295 | 295 | ||
296 | return 0; | 296 | return 0; |
297 | } | 297 | } |
@@ -971,15 +971,15 @@ static unsigned char getledstate(void) | |||
971 | return ledstate; | 971 | return ledstate; |
972 | } | 972 | } |
973 | 973 | ||
974 | void setledstate(struct kbd_struct *kbd, unsigned int led) | 974 | void setledstate(struct kbd_struct *kb, unsigned int led) |
975 | { | 975 | { |
976 | unsigned long flags; | 976 | unsigned long flags; |
977 | spin_lock_irqsave(&led_lock, flags); | 977 | spin_lock_irqsave(&led_lock, flags); |
978 | if (!(led & ~7)) { | 978 | if (!(led & ~7)) { |
979 | ledioctl = led; | 979 | ledioctl = led; |
980 | kbd->ledmode = LED_SHOW_IOCTL; | 980 | kb->ledmode = LED_SHOW_IOCTL; |
981 | } else | 981 | } else |
982 | kbd->ledmode = LED_SHOW_FLAGS; | 982 | kb->ledmode = LED_SHOW_FLAGS; |
983 | 983 | ||
984 | set_leds(); | 984 | set_leds(); |
985 | spin_unlock_irqrestore(&led_lock, flags); | 985 | spin_unlock_irqrestore(&led_lock, flags); |
@@ -987,12 +987,12 @@ void setledstate(struct kbd_struct *kbd, unsigned int led) | |||
987 | 987 | ||
988 | static inline unsigned char getleds(void) | 988 | static inline unsigned char getleds(void) |
989 | { | 989 | { |
990 | struct kbd_struct *kbd = kbd_table + fg_console; | 990 | struct kbd_struct *kb = kbd_table + fg_console; |
991 | 991 | ||
992 | if (kbd->ledmode == LED_SHOW_IOCTL) | 992 | if (kb->ledmode == LED_SHOW_IOCTL) |
993 | return ledioctl; | 993 | return ledioctl; |
994 | 994 | ||
995 | return kbd->ledflagstate; | 995 | return kb->ledflagstate; |
996 | } | 996 | } |
997 | 997 | ||
998 | static int kbd_update_leds_helper(struct input_handle *handle, void *data) | 998 | static int kbd_update_leds_helper(struct input_handle *handle, void *data) |
@@ -1018,12 +1018,12 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data) | |||
1018 | */ | 1018 | */ |
1019 | int vt_get_leds(int console, int flag) | 1019 | int vt_get_leds(int console, int flag) |
1020 | { | 1020 | { |
1021 | struct kbd_struct * kbd = kbd_table + console; | 1021 | struct kbd_struct *kb = kbd_table + console; |
1022 | int ret; | 1022 | int ret; |
1023 | unsigned long flags; | 1023 | unsigned long flags; |
1024 | 1024 | ||
1025 | spin_lock_irqsave(&led_lock, flags); | 1025 | spin_lock_irqsave(&led_lock, flags); |
1026 | ret = vc_kbd_led(kbd, flag); | 1026 | ret = vc_kbd_led(kb, flag); |
1027 | spin_unlock_irqrestore(&led_lock, flags); | 1027 | spin_unlock_irqrestore(&led_lock, flags); |
1028 | 1028 | ||
1029 | return ret; | 1029 | return ret; |
@@ -1040,8 +1040,8 @@ EXPORT_SYMBOL_GPL(vt_get_leds); | |||
1040 | */ | 1040 | */ |
1041 | void vt_set_led_state(int console, int leds) | 1041 | void vt_set_led_state(int console, int leds) |
1042 | { | 1042 | { |
1043 | struct kbd_struct * kbd = kbd_table + console; | 1043 | struct kbd_struct *kb = kbd_table + console; |
1044 | setledstate(kbd, leds); | 1044 | setledstate(kb, leds); |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | /** | 1047 | /** |
@@ -1059,10 +1059,10 @@ void vt_set_led_state(int console, int leds) | |||
1059 | */ | 1059 | */ |
1060 | void vt_kbd_con_start(int console) | 1060 | void vt_kbd_con_start(int console) |
1061 | { | 1061 | { |
1062 | struct kbd_struct * kbd = kbd_table + console; | 1062 | struct kbd_struct *kb = kbd_table + console; |
1063 | unsigned long flags; | 1063 | unsigned long flags; |
1064 | spin_lock_irqsave(&led_lock, flags); | 1064 | spin_lock_irqsave(&led_lock, flags); |
1065 | clr_vc_kbd_led(kbd, VC_SCROLLOCK); | 1065 | clr_vc_kbd_led(kb, VC_SCROLLOCK); |
1066 | set_leds(); | 1066 | set_leds(); |
1067 | spin_unlock_irqrestore(&led_lock, flags); | 1067 | spin_unlock_irqrestore(&led_lock, flags); |
1068 | } | 1068 | } |
@@ -1076,10 +1076,10 @@ void vt_kbd_con_start(int console) | |||
1076 | */ | 1076 | */ |
1077 | void vt_kbd_con_stop(int console) | 1077 | void vt_kbd_con_stop(int console) |
1078 | { | 1078 | { |
1079 | struct kbd_struct * kbd = kbd_table + console; | 1079 | struct kbd_struct *kb = kbd_table + console; |
1080 | unsigned long flags; | 1080 | unsigned long flags; |
1081 | spin_lock_irqsave(&led_lock, flags); | 1081 | spin_lock_irqsave(&led_lock, flags); |
1082 | set_vc_kbd_led(kbd, VC_SCROLLOCK); | 1082 | set_vc_kbd_led(kb, VC_SCROLLOCK); |
1083 | set_leds(); | 1083 | set_leds(); |
1084 | spin_unlock_irqrestore(&led_lock, flags); | 1084 | spin_unlock_irqrestore(&led_lock, flags); |
1085 | } | 1085 | } |
@@ -1512,15 +1512,14 @@ int __init kbd_init(void) | |||
1512 | /** | 1512 | /** |
1513 | * vt_do_diacrit - diacritical table updates | 1513 | * vt_do_diacrit - diacritical table updates |
1514 | * @cmd: ioctl request | 1514 | * @cmd: ioctl request |
1515 | * @up: pointer to user data for ioctl | 1515 | * @udp: pointer to user data for ioctl |
1516 | * @perm: permissions check computed by caller | 1516 | * @perm: permissions check computed by caller |
1517 | * | 1517 | * |
1518 | * Update the diacritical tables atomically and safely. Lock them | 1518 | * Update the diacritical tables atomically and safely. Lock them |
1519 | * against simultaneous keypresses | 1519 | * against simultaneous keypresses |
1520 | */ | 1520 | */ |
1521 | int vt_do_diacrit(unsigned int cmd, void __user *up, int perm) | 1521 | int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm) |
1522 | { | 1522 | { |
1523 | struct kbdiacrs __user *a = up; | ||
1524 | unsigned long flags; | 1523 | unsigned long flags; |
1525 | int asize; | 1524 | int asize; |
1526 | int ret = 0; | 1525 | int ret = 0; |
@@ -1528,12 +1527,13 @@ int vt_do_diacrit(unsigned int cmd, void __user *up, int perm) | |||
1528 | switch (cmd) { | 1527 | switch (cmd) { |
1529 | case KDGKBDIACR: | 1528 | case KDGKBDIACR: |
1530 | { | 1529 | { |
1531 | struct kbdiacr *diacr; | 1530 | struct kbdiacrs __user *a = udp; |
1531 | struct kbdiacr *dia; | ||
1532 | int i; | 1532 | int i; |
1533 | 1533 | ||
1534 | diacr = kmalloc(MAX_DIACR * sizeof(struct kbdiacr), | 1534 | dia = kmalloc(MAX_DIACR * sizeof(struct kbdiacr), |
1535 | GFP_KERNEL); | 1535 | GFP_KERNEL); |
1536 | if (diacr == NULL) | 1536 | if (!dia) |
1537 | return -ENOMEM; | 1537 | return -ENOMEM; |
1538 | 1538 | ||
1539 | /* Lock the diacriticals table, make a copy and then | 1539 | /* Lock the diacriticals table, make a copy and then |
@@ -1542,26 +1542,26 @@ int vt_do_diacrit(unsigned int cmd, void __user *up, int perm) | |||
1542 | 1542 | ||
1543 | asize = accent_table_size; | 1543 | asize = accent_table_size; |
1544 | for (i = 0; i < asize; i++) { | 1544 | for (i = 0; i < asize; i++) { |
1545 | diacr[i].diacr = conv_uni_to_8bit( | 1545 | dia[i].diacr = conv_uni_to_8bit( |
1546 | accent_table[i].diacr); | 1546 | accent_table[i].diacr); |
1547 | diacr[i].base = conv_uni_to_8bit( | 1547 | dia[i].base = conv_uni_to_8bit( |
1548 | accent_table[i].base); | 1548 | accent_table[i].base); |
1549 | diacr[i].result = conv_uni_to_8bit( | 1549 | dia[i].result = conv_uni_to_8bit( |
1550 | accent_table[i].result); | 1550 | accent_table[i].result); |
1551 | } | 1551 | } |
1552 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 1552 | spin_unlock_irqrestore(&kbd_event_lock, flags); |
1553 | 1553 | ||
1554 | if (put_user(asize, &a->kb_cnt)) | 1554 | if (put_user(asize, &a->kb_cnt)) |
1555 | ret = -EFAULT; | 1555 | ret = -EFAULT; |
1556 | else if (copy_to_user(a->kbdiacr, diacr, | 1556 | else if (copy_to_user(a->kbdiacr, dia, |
1557 | asize * sizeof(struct kbdiacr))) | 1557 | asize * sizeof(struct kbdiacr))) |
1558 | ret = -EFAULT; | 1558 | ret = -EFAULT; |
1559 | kfree(diacr); | 1559 | kfree(dia); |
1560 | return ret; | 1560 | return ret; |
1561 | } | 1561 | } |
1562 | case KDGKBDIACRUC: | 1562 | case KDGKBDIACRUC: |
1563 | { | 1563 | { |
1564 | struct kbdiacrsuc __user *a = up; | 1564 | struct kbdiacrsuc __user *a = udp; |
1565 | void *buf; | 1565 | void *buf; |
1566 | 1566 | ||
1567 | buf = kmalloc(MAX_DIACR * sizeof(struct kbdiacruc), | 1567 | buf = kmalloc(MAX_DIACR * sizeof(struct kbdiacruc), |
@@ -1589,8 +1589,8 @@ int vt_do_diacrit(unsigned int cmd, void __user *up, int perm) | |||
1589 | 1589 | ||
1590 | case KDSKBDIACR: | 1590 | case KDSKBDIACR: |
1591 | { | 1591 | { |
1592 | struct kbdiacrs __user *a = up; | 1592 | struct kbdiacrs __user *a = udp; |
1593 | struct kbdiacr *diacr = NULL; | 1593 | struct kbdiacr *dia = NULL; |
1594 | unsigned int ct; | 1594 | unsigned int ct; |
1595 | int i; | 1595 | int i; |
1596 | 1596 | ||
@@ -1602,14 +1602,14 @@ int vt_do_diacrit(unsigned int cmd, void __user *up, int perm) | |||
1602 | return -EINVAL; | 1602 | return -EINVAL; |
1603 | 1603 | ||
1604 | if (ct) { | 1604 | if (ct) { |
1605 | diacr = kmalloc(sizeof(struct kbdiacr) * ct, | 1605 | dia = kmalloc(sizeof(struct kbdiacr) * ct, |
1606 | GFP_KERNEL); | 1606 | GFP_KERNEL); |
1607 | if (diacr == NULL) | 1607 | if (!dia) |
1608 | return -ENOMEM; | 1608 | return -ENOMEM; |
1609 | 1609 | ||
1610 | if (copy_from_user(diacr, a->kbdiacr, | 1610 | if (copy_from_user(dia, a->kbdiacr, |
1611 | sizeof(struct kbdiacr) * ct)) { | 1611 | sizeof(struct kbdiacr) * ct)) { |
1612 | kfree(diacr); | 1612 | kfree(dia); |
1613 | return -EFAULT; | 1613 | return -EFAULT; |
1614 | } | 1614 | } |
1615 | } | 1615 | } |
@@ -1618,20 +1618,20 @@ int vt_do_diacrit(unsigned int cmd, void __user *up, int perm) | |||
1618 | accent_table_size = ct; | 1618 | accent_table_size = ct; |
1619 | for (i = 0; i < ct; i++) { | 1619 | for (i = 0; i < ct; i++) { |
1620 | accent_table[i].diacr = | 1620 | accent_table[i].diacr = |
1621 | conv_8bit_to_uni(diacr[i].diacr); | 1621 | conv_8bit_to_uni(dia[i].diacr); |
1622 | accent_table[i].base = | 1622 | accent_table[i].base = |
1623 | conv_8bit_to_uni(diacr[i].base); | 1623 | conv_8bit_to_uni(dia[i].base); |
1624 | accent_table[i].result = | 1624 | accent_table[i].result = |
1625 | conv_8bit_to_uni(diacr[i].result); | 1625 | conv_8bit_to_uni(dia[i].result); |
1626 | } | 1626 | } |
1627 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 1627 | spin_unlock_irqrestore(&kbd_event_lock, flags); |
1628 | kfree(diacr); | 1628 | kfree(dia); |
1629 | return 0; | 1629 | return 0; |
1630 | } | 1630 | } |
1631 | 1631 | ||
1632 | case KDSKBDIACRUC: | 1632 | case KDSKBDIACRUC: |
1633 | { | 1633 | { |
1634 | struct kbdiacrsuc __user *a = up; | 1634 | struct kbdiacrsuc __user *a = udp; |
1635 | unsigned int ct; | 1635 | unsigned int ct; |
1636 | void *buf = NULL; | 1636 | void *buf = NULL; |
1637 | 1637 | ||
@@ -1679,28 +1679,28 @@ int vt_do_diacrit(unsigned int cmd, void __user *up, int perm) | |||
1679 | */ | 1679 | */ |
1680 | int vt_do_kdskbmode(int console, unsigned int arg) | 1680 | int vt_do_kdskbmode(int console, unsigned int arg) |
1681 | { | 1681 | { |
1682 | struct kbd_struct * kbd = kbd_table + console; | 1682 | struct kbd_struct *kb = kbd_table + console; |
1683 | int ret = 0; | 1683 | int ret = 0; |
1684 | unsigned long flags; | 1684 | unsigned long flags; |
1685 | 1685 | ||
1686 | spin_lock_irqsave(&kbd_event_lock, flags); | 1686 | spin_lock_irqsave(&kbd_event_lock, flags); |
1687 | switch(arg) { | 1687 | switch(arg) { |
1688 | case K_RAW: | 1688 | case K_RAW: |
1689 | kbd->kbdmode = VC_RAW; | 1689 | kb->kbdmode = VC_RAW; |
1690 | break; | 1690 | break; |
1691 | case K_MEDIUMRAW: | 1691 | case K_MEDIUMRAW: |
1692 | kbd->kbdmode = VC_MEDIUMRAW; | 1692 | kb->kbdmode = VC_MEDIUMRAW; |
1693 | break; | 1693 | break; |
1694 | case K_XLATE: | 1694 | case K_XLATE: |
1695 | kbd->kbdmode = VC_XLATE; | 1695 | kb->kbdmode = VC_XLATE; |
1696 | do_compute_shiftstate(); | 1696 | do_compute_shiftstate(); |
1697 | break; | 1697 | break; |
1698 | case K_UNICODE: | 1698 | case K_UNICODE: |
1699 | kbd->kbdmode = VC_UNICODE; | 1699 | kb->kbdmode = VC_UNICODE; |
1700 | do_compute_shiftstate(); | 1700 | do_compute_shiftstate(); |
1701 | break; | 1701 | break; |
1702 | case K_OFF: | 1702 | case K_OFF: |
1703 | kbd->kbdmode = VC_OFF; | 1703 | kb->kbdmode = VC_OFF; |
1704 | break; | 1704 | break; |
1705 | default: | 1705 | default: |
1706 | ret = -EINVAL; | 1706 | ret = -EINVAL; |
@@ -1719,17 +1719,17 @@ int vt_do_kdskbmode(int console, unsigned int arg) | |||
1719 | */ | 1719 | */ |
1720 | int vt_do_kdskbmeta(int console, unsigned int arg) | 1720 | int vt_do_kdskbmeta(int console, unsigned int arg) |
1721 | { | 1721 | { |
1722 | struct kbd_struct * kbd = kbd_table + console; | 1722 | struct kbd_struct *kb = kbd_table + console; |
1723 | int ret = 0; | 1723 | int ret = 0; |
1724 | unsigned long flags; | 1724 | unsigned long flags; |
1725 | 1725 | ||
1726 | spin_lock_irqsave(&kbd_event_lock, flags); | 1726 | spin_lock_irqsave(&kbd_event_lock, flags); |
1727 | switch(arg) { | 1727 | switch(arg) { |
1728 | case K_METABIT: | 1728 | case K_METABIT: |
1729 | clr_vc_kbd_mode(kbd, VC_META); | 1729 | clr_vc_kbd_mode(kb, VC_META); |
1730 | break; | 1730 | break; |
1731 | case K_ESCPREFIX: | 1731 | case K_ESCPREFIX: |
1732 | set_vc_kbd_mode(kbd, VC_META); | 1732 | set_vc_kbd_mode(kb, VC_META); |
1733 | break; | 1733 | break; |
1734 | default: | 1734 | default: |
1735 | ret = -EINVAL; | 1735 | ret = -EINVAL; |
@@ -1768,7 +1768,7 @@ int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, | |||
1768 | int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, | 1768 | int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, |
1769 | int console) | 1769 | int console) |
1770 | { | 1770 | { |
1771 | struct kbd_struct * kbd = kbd_table + console; | 1771 | struct kbd_struct *kb = kbd_table + console; |
1772 | struct kbentry tmp; | 1772 | struct kbentry tmp; |
1773 | ushort *key_map, *new_map, val, ov; | 1773 | ushort *key_map, *new_map, val, ov; |
1774 | unsigned long flags; | 1774 | unsigned long flags; |
@@ -1786,7 +1786,7 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, | |||
1786 | key_map = key_maps[s]; | 1786 | key_map = key_maps[s]; |
1787 | if (key_map) { | 1787 | if (key_map) { |
1788 | val = U(key_map[i]); | 1788 | val = U(key_map[i]); |
1789 | if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES) | 1789 | if (kb->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES) |
1790 | val = K_HOLE; | 1790 | val = K_HOLE; |
1791 | } else | 1791 | } else |
1792 | val = (i ? K_HOLE : K_NOSUCHMAP); | 1792 | val = (i ? K_HOLE : K_NOSUCHMAP); |
@@ -1814,7 +1814,7 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, | |||
1814 | if (KVAL(v) > max_vals[KTYP(v)]) | 1814 | if (KVAL(v) > max_vals[KTYP(v)]) |
1815 | return -EINVAL; | 1815 | return -EINVAL; |
1816 | } else | 1816 | } else |
1817 | if (kbd->kbdmode != VC_UNICODE) | 1817 | if (kb->kbdmode != VC_UNICODE) |
1818 | return -EINVAL; | 1818 | return -EINVAL; |
1819 | 1819 | ||
1820 | /* ++Geert: non-PC keyboards may generate keycode zero */ | 1820 | /* ++Geert: non-PC keyboards may generate keycode zero */ |
@@ -1985,7 +1985,7 @@ reterr: | |||
1985 | 1985 | ||
1986 | int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) | 1986 | int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) |
1987 | { | 1987 | { |
1988 | struct kbd_struct * kbd = kbd_table + console; | 1988 | struct kbd_struct *kb = kbd_table + console; |
1989 | unsigned long flags; | 1989 | unsigned long flags; |
1990 | unsigned char ucval; | 1990 | unsigned char ucval; |
1991 | 1991 | ||
@@ -1994,7 +1994,7 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) | |||
1994 | /* don't use them - they will go away without warning */ | 1994 | /* don't use them - they will go away without warning */ |
1995 | case KDGKBLED: | 1995 | case KDGKBLED: |
1996 | spin_lock_irqsave(&kbd_event_lock, flags); | 1996 | spin_lock_irqsave(&kbd_event_lock, flags); |
1997 | ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4); | 1997 | ucval = kb->ledflagstate | (kb->default_ledflagstate << 4); |
1998 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 1998 | spin_unlock_irqrestore(&kbd_event_lock, flags); |
1999 | return put_user(ucval, (char __user *)arg); | 1999 | return put_user(ucval, (char __user *)arg); |
2000 | 2000 | ||
@@ -2004,8 +2004,8 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) | |||
2004 | if (arg & ~0x77) | 2004 | if (arg & ~0x77) |
2005 | return -EINVAL; | 2005 | return -EINVAL; |
2006 | spin_lock_irqsave(&led_lock, flags); | 2006 | spin_lock_irqsave(&led_lock, flags); |
2007 | kbd->ledflagstate = (arg & 7); | 2007 | kb->ledflagstate = (arg & 7); |
2008 | kbd->default_ledflagstate = ((arg >> 4) & 7); | 2008 | kb->default_ledflagstate = ((arg >> 4) & 7); |
2009 | set_leds(); | 2009 | set_leds(); |
2010 | spin_unlock_irqrestore(&led_lock, flags); | 2010 | spin_unlock_irqrestore(&led_lock, flags); |
2011 | return 0; | 2011 | return 0; |
@@ -2019,7 +2019,7 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) | |||
2019 | case KDSETLED: | 2019 | case KDSETLED: |
2020 | if (!perm) | 2020 | if (!perm) |
2021 | return -EPERM; | 2021 | return -EPERM; |
2022 | setledstate(kbd, arg); | 2022 | setledstate(kb, arg); |
2023 | return 0; | 2023 | return 0; |
2024 | } | 2024 | } |
2025 | return -ENOIOCTLCMD; | 2025 | return -ENOIOCTLCMD; |
@@ -2027,9 +2027,9 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) | |||
2027 | 2027 | ||
2028 | int vt_do_kdgkbmode(int console) | 2028 | int vt_do_kdgkbmode(int console) |
2029 | { | 2029 | { |
2030 | struct kbd_struct * kbd = kbd_table + console; | 2030 | struct kbd_struct *kb = kbd_table + console; |
2031 | /* This is a spot read so needs no locking */ | 2031 | /* This is a spot read so needs no locking */ |
2032 | switch (kbd->kbdmode) { | 2032 | switch (kb->kbdmode) { |
2033 | case VC_RAW: | 2033 | case VC_RAW: |
2034 | return K_RAW; | 2034 | return K_RAW; |
2035 | case VC_MEDIUMRAW: | 2035 | case VC_MEDIUMRAW: |
@@ -2051,9 +2051,9 @@ int vt_do_kdgkbmode(int console) | |||
2051 | */ | 2051 | */ |
2052 | int vt_do_kdgkbmeta(int console) | 2052 | int vt_do_kdgkbmeta(int console) |
2053 | { | 2053 | { |
2054 | struct kbd_struct * kbd = kbd_table + console; | 2054 | struct kbd_struct *kb = kbd_table + console; |
2055 | /* Again a spot read so no locking */ | 2055 | /* Again a spot read so no locking */ |
2056 | return vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT; | 2056 | return vc_kbd_mode(kb, VC_META) ? K_ESCPREFIX : K_METABIT; |
2057 | } | 2057 | } |
2058 | 2058 | ||
2059 | /** | 2059 | /** |
@@ -2092,19 +2092,19 @@ int vt_get_shift_state(void) | |||
2092 | */ | 2092 | */ |
2093 | void vt_reset_keyboard(int console) | 2093 | void vt_reset_keyboard(int console) |
2094 | { | 2094 | { |
2095 | struct kbd_struct * kbd = kbd_table + console; | 2095 | struct kbd_struct *kb = kbd_table + console; |
2096 | unsigned long flags; | 2096 | unsigned long flags; |
2097 | 2097 | ||
2098 | spin_lock_irqsave(&kbd_event_lock, flags); | 2098 | spin_lock_irqsave(&kbd_event_lock, flags); |
2099 | set_vc_kbd_mode(kbd, VC_REPEAT); | 2099 | set_vc_kbd_mode(kb, VC_REPEAT); |
2100 | clr_vc_kbd_mode(kbd, VC_CKMODE); | 2100 | clr_vc_kbd_mode(kb, VC_CKMODE); |
2101 | clr_vc_kbd_mode(kbd, VC_APPLIC); | 2101 | clr_vc_kbd_mode(kb, VC_APPLIC); |
2102 | clr_vc_kbd_mode(kbd, VC_CRLF); | 2102 | clr_vc_kbd_mode(kb, VC_CRLF); |
2103 | kbd->lockstate = 0; | 2103 | kb->lockstate = 0; |
2104 | kbd->slockstate = 0; | 2104 | kb->slockstate = 0; |
2105 | spin_lock(&led_lock); | 2105 | spin_lock(&led_lock); |
2106 | kbd->ledmode = LED_SHOW_FLAGS; | 2106 | kb->ledmode = LED_SHOW_FLAGS; |
2107 | kbd->ledflagstate = kbd->default_ledflagstate; | 2107 | kb->ledflagstate = kb->default_ledflagstate; |
2108 | spin_unlock(&led_lock); | 2108 | spin_unlock(&led_lock); |
2109 | /* do not do set_leds here because this causes an endless tasklet loop | 2109 | /* do not do set_leds here because this causes an endless tasklet loop |
2110 | when the keyboard hasn't been initialized yet */ | 2110 | when the keyboard hasn't been initialized yet */ |
@@ -2122,8 +2122,8 @@ void vt_reset_keyboard(int console) | |||
2122 | 2122 | ||
2123 | int vt_get_kbd_mode_bit(int console, int bit) | 2123 | int vt_get_kbd_mode_bit(int console, int bit) |
2124 | { | 2124 | { |
2125 | struct kbd_struct * kbd = kbd_table + console; | 2125 | struct kbd_struct *kb = kbd_table + console; |
2126 | return vc_kbd_mode(kbd, bit); | 2126 | return vc_kbd_mode(kb, bit); |
2127 | } | 2127 | } |
2128 | 2128 | ||
2129 | /** | 2129 | /** |
@@ -2137,11 +2137,11 @@ int vt_get_kbd_mode_bit(int console, int bit) | |||
2137 | 2137 | ||
2138 | void vt_set_kbd_mode_bit(int console, int bit) | 2138 | void vt_set_kbd_mode_bit(int console, int bit) |
2139 | { | 2139 | { |
2140 | struct kbd_struct * kbd = kbd_table + console; | 2140 | struct kbd_struct *kb = kbd_table + console; |
2141 | unsigned long flags; | 2141 | unsigned long flags; |
2142 | 2142 | ||
2143 | spin_lock_irqsave(&kbd_event_lock, flags); | 2143 | spin_lock_irqsave(&kbd_event_lock, flags); |
2144 | set_vc_kbd_mode(kbd, bit); | 2144 | set_vc_kbd_mode(kb, bit); |
2145 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 2145 | spin_unlock_irqrestore(&kbd_event_lock, flags); |
2146 | } | 2146 | } |
2147 | 2147 | ||
@@ -2156,10 +2156,10 @@ void vt_set_kbd_mode_bit(int console, int bit) | |||
2156 | 2156 | ||
2157 | void vt_clr_kbd_mode_bit(int console, int bit) | 2157 | void vt_clr_kbd_mode_bit(int console, int bit) |
2158 | { | 2158 | { |
2159 | struct kbd_struct * kbd = kbd_table + console; | 2159 | struct kbd_struct *kb = kbd_table + console; |
2160 | unsigned long flags; | 2160 | unsigned long flags; |
2161 | 2161 | ||
2162 | spin_lock_irqsave(&kbd_event_lock, flags); | 2162 | spin_lock_irqsave(&kbd_event_lock, flags); |
2163 | clr_vc_kbd_mode(kbd, bit); | 2163 | clr_vc_kbd_mode(kb, bit); |
2164 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 2164 | spin_unlock_irqrestore(&kbd_event_lock, flags); |
2165 | } | 2165 | } |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 8a23c53b946e..12b0e67473ba 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -834,7 +834,6 @@ static void digi_set_termios(struct tty_struct *tty, | |||
834 | arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; | 834 | arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; |
835 | } else { | 835 | } else { |
836 | arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; | 836 | arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; |
837 | tty->hw_stopped = 0; | ||
838 | } | 837 | } |
839 | 838 | ||
840 | buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; | 839 | buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; |
@@ -1500,15 +1499,11 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1500 | if (val & DIGI_READ_INPUT_SIGNALS_CTS) { | 1499 | if (val & DIGI_READ_INPUT_SIGNALS_CTS) { |
1501 | priv->dp_modem_signals |= TIOCM_CTS; | 1500 | priv->dp_modem_signals |= TIOCM_CTS; |
1502 | /* port must be open to use tty struct */ | 1501 | /* port must be open to use tty struct */ |
1503 | if (rts) { | 1502 | if (rts) |
1504 | tty->hw_stopped = 0; | ||
1505 | tty_port_tty_wakeup(&port->port); | 1503 | tty_port_tty_wakeup(&port->port); |
1506 | } | ||
1507 | } else { | 1504 | } else { |
1508 | priv->dp_modem_signals &= ~TIOCM_CTS; | 1505 | priv->dp_modem_signals &= ~TIOCM_CTS; |
1509 | /* port must be open to use tty struct */ | 1506 | /* port must be open to use tty struct */ |
1510 | if (rts) | ||
1511 | tty->hw_stopped = 1; | ||
1512 | } | 1507 | } |
1513 | if (val & DIGI_READ_INPUT_SIGNALS_DSR) | 1508 | if (val & DIGI_READ_INPUT_SIGNALS_DSR) |
1514 | priv->dp_modem_signals |= TIOCM_DSR; | 1509 | priv->dp_modem_signals |= TIOCM_DSR; |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index c0a42e9e6777..ddbb8fe1046d 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -1456,12 +1456,8 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr) | |||
1456 | tty = tty_port_tty_get(&edge_port->port->port); | 1456 | tty = tty_port_tty_get(&edge_port->port->port); |
1457 | /* handle CTS flow control */ | 1457 | /* handle CTS flow control */ |
1458 | if (tty && C_CRTSCTS(tty)) { | 1458 | if (tty && C_CRTSCTS(tty)) { |
1459 | if (msr & EDGEPORT_MSR_CTS) { | 1459 | if (msr & EDGEPORT_MSR_CTS) |
1460 | tty->hw_stopped = 0; | ||
1461 | tty_wakeup(tty); | 1460 | tty_wakeup(tty); |
1462 | } else { | ||
1463 | tty->hw_stopped = 1; | ||
1464 | } | ||
1465 | } | 1461 | } |
1466 | tty_kref_put(tty); | 1462 | tty_kref_put(tty); |
1467 | } | 1463 | } |
@@ -2177,7 +2173,6 @@ static void change_port_settings(struct tty_struct *tty, | |||
2177 | dev_dbg(dev, "%s - RTS/CTS is enabled\n", __func__); | 2173 | dev_dbg(dev, "%s - RTS/CTS is enabled\n", __func__); |
2178 | } else { | 2174 | } else { |
2179 | dev_dbg(dev, "%s - RTS/CTS is disabled\n", __func__); | 2175 | dev_dbg(dev, "%s - RTS/CTS is disabled\n", __func__); |
2180 | tty->hw_stopped = 0; | ||
2181 | restart_read(edge_port); | 2176 | restart_read(edge_port); |
2182 | } | 2177 | } |
2183 | 2178 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 3dd3ff8c50d3..e9da41d9fe7f 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -773,7 +773,6 @@ static void ti_set_termios(struct tty_struct *tty, | |||
773 | config->wFlags |= TI_UART_ENABLE_RTS_IN; | 773 | config->wFlags |= TI_UART_ENABLE_RTS_IN; |
774 | config->wFlags |= TI_UART_ENABLE_CTS_OUT; | 774 | config->wFlags |= TI_UART_ENABLE_CTS_OUT; |
775 | } else { | 775 | } else { |
776 | tty->hw_stopped = 0; | ||
777 | ti_restart_read(tport, tty); | 776 | ti_restart_read(tport, tty); |
778 | } | 777 | } |
779 | 778 | ||
@@ -1291,12 +1290,8 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr) | |||
1291 | /* handle CTS flow control */ | 1290 | /* handle CTS flow control */ |
1292 | tty = tty_port_tty_get(&tport->tp_port->port); | 1291 | tty = tty_port_tty_get(&tport->tp_port->port); |
1293 | if (tty && C_CRTSCTS(tty)) { | 1292 | if (tty && C_CRTSCTS(tty)) { |
1294 | if (msr & TI_MSR_CTS) { | 1293 | if (msr & TI_MSR_CTS) |
1295 | tty->hw_stopped = 0; | ||
1296 | tty_wakeup(tty); | 1294 | tty_wakeup(tty); |
1297 | } else { | ||
1298 | tty->hw_stopped = 1; | ||
1299 | } | ||
1300 | } | 1295 | } |
1301 | tty_kref_put(tty); | 1296 | tty_kref_put(tty); |
1302 | } | 1297 | } |