diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 16:41:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 16:41:04 -0500 |
commit | 21eaab6d19ed43e82ed39c8deb7f192134fb4a0e (patch) | |
tree | d995205afdcb7f47462bcd28067dc0c4ab0b7b02 /drivers | |
parent | 74e1a2a39355b2d3ae8c60c78d8add162c6d7183 (diff) | |
parent | 9e17df37d710f8998e9cb10a548304fe33d4a5c2 (diff) |
Merge tag 'tty-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial patches from Greg Kroah-Hartman:
"Here's the big tty/serial driver patches for 3.9-rc1.
More tty port rework and fixes from Jiri here, as well as lots of
individual serial driver updates and fixes.
All of these have been in the linux-next tree for a while."
* tag 'tty-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (140 commits)
tty: mxser: improve error handling in mxser_probe() and mxser_module_init()
serial: imx: fix uninitialized variable warning
serial: tegra: assume CONFIG_OF
TTY: do not update atime/mtime on read/write
lguest: select CONFIG_TTY to build properly.
ARM defconfigs: add missing inclusions of linux/platform_device.h
fb/exynos: include platform_device.h
ARM: sa1100/assabet: include platform_device.h directly
serial: imx: Fix recursive locking bug
pps: Fix build breakage from decoupling pps from tty
tty: Remove ancient hardpps()
pps: Additional cleanups in uart_handle_dcd_change
pps: Move timestamp read into PPS code proper
pps: Don't crash the machine when exiting will do
pps: Fix a use-after free bug when unregistering a source.
pps: Use pps_lookup_dev to reduce ldisc coupling
pps: Add pps_lookup_dev() function
tty: serial: uartlite: Support uartlite on big and little endian systems
tty: serial: uartlite: Fix sparse and checkpatch warnings
serial/arc-uart: Miscll DT related updates (Grant's review comments)
...
Fix up trivial conflicts, mostly just due to the TTY config option
clashing with the EXPERIMENTAL removal.
Diffstat (limited to 'drivers')
214 files changed, 6442 insertions, 2354 deletions
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index e9f203eadb1f..fdfd61a2d523 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -26,6 +26,7 @@ config BT_HCIBTSDIO | |||
26 | 26 | ||
27 | config BT_HCIUART | 27 | config BT_HCIUART |
28 | tristate "HCI UART driver" | 28 | tristate "HCI UART driver" |
29 | depends on TTY | ||
29 | help | 30 | help |
30 | Bluetooth HCI UART driver. | 31 | Bluetooth HCI UART driver. |
31 | This driver is required if you want to use Bluetooth devices with | 32 | This driver is required if you want to use Bluetooth devices with |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 72bedad6bf8c..3bb6fa3930be 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -53,7 +53,7 @@ source "drivers/tty/serial/Kconfig" | |||
53 | 53 | ||
54 | config TTY_PRINTK | 54 | config TTY_PRINTK |
55 | bool "TTY driver to output user messages via printk" | 55 | bool "TTY driver to output user messages via printk" |
56 | depends on EXPERT | 56 | depends on EXPERT && TTY |
57 | default n | 57 | default n |
58 | ---help--- | 58 | ---help--- |
59 | If you say Y here, the support for writing user messages (i.e. | 59 | If you say Y here, the support for writing user messages (i.e. |
@@ -159,7 +159,7 @@ source "drivers/tty/hvc/Kconfig" | |||
159 | 159 | ||
160 | config VIRTIO_CONSOLE | 160 | config VIRTIO_CONSOLE |
161 | tristate "Virtio console" | 161 | tristate "Virtio console" |
162 | depends on VIRTIO | 162 | depends on VIRTIO && TTY |
163 | select HVC_DRIVER | 163 | select HVC_DRIVER |
164 | help | 164 | help |
165 | Virtio console for use with lguest and other hypervisors. | 165 | Virtio console for use with lguest and other hypervisors. |
@@ -392,6 +392,7 @@ config XILINX_HWICAP | |||
392 | 392 | ||
393 | config R3964 | 393 | config R3964 |
394 | tristate "Siemens R3964 line discipline" | 394 | tristate "Siemens R3964 line discipline" |
395 | depends on TTY | ||
395 | ---help--- | 396 | ---help--- |
396 | This driver allows synchronous communication with devices using the | 397 | This driver allows synchronous communication with devices using the |
397 | Siemens R3964 packet protocol. Unless you are dealing with special | 398 | Siemens R3964 packet protocol. Unless you are dealing with special |
@@ -439,7 +440,7 @@ source "drivers/char/pcmcia/Kconfig" | |||
439 | 440 | ||
440 | config MWAVE | 441 | config MWAVE |
441 | tristate "ACP Modem (Mwave) support" | 442 | tristate "ACP Modem (Mwave) support" |
442 | depends on X86 | 443 | depends on X86 && TTY |
443 | select SERIAL_8250 | 444 | select SERIAL_8250 |
444 | ---help--- | 445 | ---help--- |
445 | The ACP modem (Mwave) for Linux is a WinModem. It is composed of a | 446 | The ACP modem (Mwave) for Linux is a WinModem. It is composed of a |
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig index 6614416a8623..2a166d56738a 100644 --- a/drivers/char/pcmcia/Kconfig +++ b/drivers/char/pcmcia/Kconfig | |||
@@ -7,7 +7,7 @@ menu "PCMCIA character devices" | |||
7 | 7 | ||
8 | config SYNCLINK_CS | 8 | config SYNCLINK_CS |
9 | tristate "SyncLink PC Card support" | 9 | tristate "SyncLink PC Card support" |
10 | depends on PCMCIA | 10 | depends on PCMCIA && TTY |
11 | help | 11 | help |
12 | Enable support for the SyncLink PC Card serial adapter, running | 12 | Enable support for the SyncLink PC Card serial adapter, running |
13 | asynchronous and HDLC communications up to 512Kbps. The port is | 13 | asynchronous and HDLC communications up to 512Kbps. The port is |
@@ -45,7 +45,7 @@ config CARDMAN_4040 | |||
45 | 45 | ||
46 | config IPWIRELESS | 46 | config IPWIRELESS |
47 | tristate "IPWireless 3G UMTS PCMCIA card support" | 47 | tristate "IPWireless 3G UMTS PCMCIA card support" |
48 | depends on PCMCIA && NETDEVICES | 48 | depends on PCMCIA && NETDEVICES && TTY |
49 | select PPP | 49 | select PPP |
50 | help | 50 | help |
51 | This is a driver for 3G UMTS PCMCIA card from IPWireless company. In | 51 | This is a driver for 3G UMTS PCMCIA card from IPWireless company. In |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index b66eaa04f8cb..d0c9852ab875 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -210,7 +210,7 @@ typedef struct _mgslpc_info { | |||
210 | char testing_irq; | 210 | char testing_irq; |
211 | unsigned int init_error; /* startup error (DIAGS) */ | 211 | unsigned int init_error; /* startup error (DIAGS) */ |
212 | 212 | ||
213 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 213 | char *flag_buf; |
214 | bool drop_rts_on_tx_done; | 214 | bool drop_rts_on_tx_done; |
215 | 215 | ||
216 | struct _input_signal_events input_signal_events; | 216 | struct _input_signal_events input_signal_events; |
@@ -765,9 +765,6 @@ static void bh_handler(struct work_struct *work) | |||
765 | struct tty_struct *tty; | 765 | struct tty_struct *tty; |
766 | int action; | 766 | int action; |
767 | 767 | ||
768 | if (!info) | ||
769 | return; | ||
770 | |||
771 | if (debug_level >= DEBUG_LEVEL_BH) | 768 | if (debug_level >= DEBUG_LEVEL_BH) |
772 | printk( "%s(%d):bh_handler(%s) entry\n", | 769 | printk( "%s(%d):bh_handler(%s) entry\n", |
773 | __FILE__,__LINE__,info->device_name); | 770 | __FILE__,__LINE__,info->device_name); |
@@ -886,21 +883,14 @@ static void rx_ready_hdlc(MGSLPC_INFO *info, int eom) | |||
886 | issue_command(info, CHA, CMD_RXFIFO); | 883 | issue_command(info, CHA, CMD_RXFIFO); |
887 | } | 884 | } |
888 | 885 | ||
889 | static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) | 886 | static void rx_ready_async(MGSLPC_INFO *info, int tcd) |
890 | { | 887 | { |
888 | struct tty_port *port = &info->port; | ||
891 | unsigned char data, status, flag; | 889 | unsigned char data, status, flag; |
892 | int fifo_count; | 890 | int fifo_count; |
893 | int work = 0; | 891 | int work = 0; |
894 | struct mgsl_icount *icount = &info->icount; | 892 | struct mgsl_icount *icount = &info->icount; |
895 | 893 | ||
896 | if (!tty) { | ||
897 | /* tty is not available anymore */ | ||
898 | issue_command(info, CHA, CMD_RXRESET); | ||
899 | if (debug_level >= DEBUG_LEVEL_ISR) | ||
900 | printk("%s(%d):rx_ready_async(tty=NULL)\n",__FILE__,__LINE__); | ||
901 | return; | ||
902 | } | ||
903 | |||
904 | if (tcd) { | 894 | if (tcd) { |
905 | /* early termination, get FIFO count from RBCL register */ | 895 | /* early termination, get FIFO count from RBCL register */ |
906 | fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f); | 896 | fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f); |
@@ -913,7 +903,7 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) | |||
913 | } else | 903 | } else |
914 | fifo_count = 32; | 904 | fifo_count = 32; |
915 | 905 | ||
916 | tty_buffer_request_room(tty, fifo_count); | 906 | tty_buffer_request_room(port, fifo_count); |
917 | /* Flush received async data to receive data buffer. */ | 907 | /* Flush received async data to receive data buffer. */ |
918 | while (fifo_count) { | 908 | while (fifo_count) { |
919 | data = read_reg(info, CHA + RXFIFO); | 909 | data = read_reg(info, CHA + RXFIFO); |
@@ -944,7 +934,7 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) | |||
944 | else if (status & BIT6) | 934 | else if (status & BIT6) |
945 | flag = TTY_FRAME; | 935 | flag = TTY_FRAME; |
946 | } | 936 | } |
947 | work += tty_insert_flip_char(tty, data, flag); | 937 | work += tty_insert_flip_char(port, data, flag); |
948 | } | 938 | } |
949 | issue_command(info, CHA, CMD_RXFIFO); | 939 | issue_command(info, CHA, CMD_RXFIFO); |
950 | 940 | ||
@@ -957,7 +947,7 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) | |||
957 | } | 947 | } |
958 | 948 | ||
959 | if (work) | 949 | if (work) |
960 | tty_flip_buffer_push(tty); | 950 | tty_flip_buffer_push(port); |
961 | } | 951 | } |
962 | 952 | ||
963 | 953 | ||
@@ -1217,7 +1207,7 @@ static irqreturn_t mgslpc_isr(int dummy, void *dev_id) | |||
1217 | if (info->params.mode == MGSL_MODE_HDLC) | 1207 | if (info->params.mode == MGSL_MODE_HDLC) |
1218 | rx_ready_hdlc(info, isr & IRQ_RXEOM); | 1208 | rx_ready_hdlc(info, isr & IRQ_RXEOM); |
1219 | else | 1209 | else |
1220 | rx_ready_async(info, isr & IRQ_RXEOM, tty); | 1210 | rx_ready_async(info, isr & IRQ_RXEOM); |
1221 | } | 1211 | } |
1222 | 1212 | ||
1223 | /* transmit IRQs */ | 1213 | /* transmit IRQs */ |
@@ -1353,7 +1343,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) | |||
1353 | reset_device(info); | 1343 | reset_device(info); |
1354 | 1344 | ||
1355 | if (!tty || tty->termios.c_cflag & HUPCL) { | 1345 | if (!tty || tty->termios.c_cflag & HUPCL) { |
1356 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 1346 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1357 | set_signals(info); | 1347 | set_signals(info); |
1358 | } | 1348 | } |
1359 | 1349 | ||
@@ -1415,12 +1405,12 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty) | |||
1415 | 1405 | ||
1416 | cflag = tty->termios.c_cflag; | 1406 | cflag = tty->termios.c_cflag; |
1417 | 1407 | ||
1418 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 1408 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
1419 | /* otherwise assert DTR and RTS */ | 1409 | /* otherwise assert RTS and DTR */ |
1420 | if (cflag & CBAUD) | 1410 | if (cflag & CBAUD) |
1421 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 1411 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
1422 | else | 1412 | else |
1423 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 1413 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1424 | 1414 | ||
1425 | /* byte size and parity */ | 1415 | /* byte size and parity */ |
1426 | 1416 | ||
@@ -2311,7 +2301,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2311 | /* Handle transition to B0 status */ | 2301 | /* Handle transition to B0 status */ |
2312 | if (old_termios->c_cflag & CBAUD && | 2302 | if (old_termios->c_cflag & CBAUD && |
2313 | !(tty->termios.c_cflag & CBAUD)) { | 2303 | !(tty->termios.c_cflag & CBAUD)) { |
2314 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2304 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2315 | spin_lock_irqsave(&info->lock,flags); | 2305 | spin_lock_irqsave(&info->lock,flags); |
2316 | set_signals(info); | 2306 | set_signals(info); |
2317 | spin_unlock_irqrestore(&info->lock,flags); | 2307 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -2474,9 +2464,9 @@ static void dtr_rts(struct tty_port *port, int onoff) | |||
2474 | 2464 | ||
2475 | spin_lock_irqsave(&info->lock,flags); | 2465 | spin_lock_irqsave(&info->lock,flags); |
2476 | if (onoff) | 2466 | if (onoff) |
2477 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 2467 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
2478 | else | 2468 | else |
2479 | info->serial_signals &= ~SerialSignal_RTS + SerialSignal_DTR; | 2469 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2480 | set_signals(info); | 2470 | set_signals(info); |
2481 | spin_unlock_irqrestore(&info->lock,flags); | 2471 | spin_unlock_irqrestore(&info->lock,flags); |
2482 | } | 2472 | } |
@@ -2521,7 +2511,7 @@ static int mgslpc_open(struct tty_struct *tty, struct file * filp) | |||
2521 | goto cleanup; | 2511 | goto cleanup; |
2522 | } | 2512 | } |
2523 | 2513 | ||
2524 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 2514 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
2525 | 2515 | ||
2526 | spin_lock_irqsave(&info->netlock, flags); | 2516 | spin_lock_irqsave(&info->netlock, flags); |
2527 | if (info->netcount) { | 2517 | if (info->netcount) { |
@@ -2674,6 +2664,14 @@ static int rx_alloc_buffers(MGSLPC_INFO *info) | |||
2674 | if (info->rx_buf == NULL) | 2664 | if (info->rx_buf == NULL) |
2675 | return -ENOMEM; | 2665 | return -ENOMEM; |
2676 | 2666 | ||
2667 | /* unused flag buffer to satisfy receive_buf calling interface */ | ||
2668 | info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL); | ||
2669 | if (!info->flag_buf) { | ||
2670 | kfree(info->rx_buf); | ||
2671 | info->rx_buf = NULL; | ||
2672 | return -ENOMEM; | ||
2673 | } | ||
2674 | |||
2677 | rx_reset_buffers(info); | 2675 | rx_reset_buffers(info); |
2678 | return 0; | 2676 | return 0; |
2679 | } | 2677 | } |
@@ -2682,6 +2680,8 @@ static void rx_free_buffers(MGSLPC_INFO *info) | |||
2682 | { | 2680 | { |
2683 | kfree(info->rx_buf); | 2681 | kfree(info->rx_buf); |
2684 | info->rx_buf = NULL; | 2682 | info->rx_buf = NULL; |
2683 | kfree(info->flag_buf); | ||
2684 | info->flag_buf = NULL; | ||
2685 | } | 2685 | } |
2686 | 2686 | ||
2687 | static int claim_resources(MGSLPC_INFO *info) | 2687 | static int claim_resources(MGSLPC_INFO *info) |
@@ -3575,8 +3575,8 @@ static void get_signals(MGSLPC_INFO *info) | |||
3575 | { | 3575 | { |
3576 | unsigned char status = 0; | 3576 | unsigned char status = 0; |
3577 | 3577 | ||
3578 | /* preserve DTR and RTS */ | 3578 | /* preserve RTS and DTR */ |
3579 | info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; | 3579 | info->serial_signals &= SerialSignal_RTS | SerialSignal_DTR; |
3580 | 3580 | ||
3581 | if (read_reg(info, CHB + VSTR) & BIT7) | 3581 | if (read_reg(info, CHB + VSTR) & BIT7) |
3582 | info->serial_signals |= SerialSignal_DCD; | 3582 | info->serial_signals |= SerialSignal_DCD; |
@@ -3590,7 +3590,7 @@ static void get_signals(MGSLPC_INFO *info) | |||
3590 | info->serial_signals |= SerialSignal_DSR; | 3590 | info->serial_signals |= SerialSignal_DSR; |
3591 | } | 3591 | } |
3592 | 3592 | ||
3593 | /* Set the state of DTR and RTS based on contents of | 3593 | /* Set the state of RTS and DTR based on contents of |
3594 | * serial_signals member of device extension. | 3594 | * serial_signals member of device extension. |
3595 | */ | 3595 | */ |
3596 | static void set_signals(MGSLPC_INFO *info) | 3596 | static void set_signals(MGSLPC_INFO *info) |
@@ -4009,8 +4009,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
4009 | spin_unlock_irqrestore(&info->netlock, flags); | 4009 | spin_unlock_irqrestore(&info->netlock, flags); |
4010 | return rc; | 4010 | return rc; |
4011 | } | 4011 | } |
4012 | /* assert DTR and RTS, apply hardware settings */ | 4012 | /* assert RTS and DTR, apply hardware settings */ |
4013 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 4013 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
4014 | mgslpc_program_hw(info, tty); | 4014 | mgslpc_program_hw(info, tty); |
4015 | tty_kref_put(tty); | 4015 | tty_kref_put(tty); |
4016 | 4016 | ||
diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 51044cc55cf2..88d9ef6b5b4a 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/module.h> | ||
30 | #include <drm/drmP.h> | 31 | #include <drm/drmP.h> |
31 | #include <drm/drm_crtc.h> | 32 | #include <drm/drm_crtc.h> |
32 | #include <drm/drm_crtc_helper.h> | 33 | #include <drm/drm_crtc_helper.h> |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 9b94a78ca776..8bb810e1900b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -802,6 +802,7 @@ config I2C_PARPORT_LIGHT | |||
802 | 802 | ||
803 | config I2C_TAOS_EVM | 803 | config I2C_TAOS_EVM |
804 | tristate "TAOS evaluation module" | 804 | tristate "TAOS evaluation module" |
805 | depends on TTY | ||
805 | select SERIO | 806 | select SERIO |
806 | select SERIO_SERPORT | 807 | select SERIO_SERPORT |
807 | default n | 808 | default n |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 560c243bfcaf..6e9cc765e0dc 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -36,6 +36,7 @@ config SERIO_I8042 | |||
36 | config SERIO_SERPORT | 36 | config SERIO_SERPORT |
37 | tristate "Serial port line discipline" | 37 | tristate "Serial port line discipline" |
38 | default y | 38 | default y |
39 | depends on TTY | ||
39 | help | 40 | help |
40 | Say Y here if you plan to use an input device (mouse, joystick, | 41 | Say Y here if you plan to use an input device (mouse, joystick, |
41 | tablet, 6dof) that communicates over the RS232 serial (COM) port. | 42 | tablet, 6dof) that communicates over the RS232 serial (COM) port. |
diff --git a/drivers/ipack/devices/Kconfig b/drivers/ipack/devices/Kconfig index 0b82fdc198c0..907a8cb48f2a 100644 --- a/drivers/ipack/devices/Kconfig +++ b/drivers/ipack/devices/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SERIAL_IPOCTAL | 1 | config SERIAL_IPOCTAL |
2 | tristate "IndustryPack IP-OCTAL uart support" | 2 | tristate "IndustryPack IP-OCTAL uart support" |
3 | depends on IPACK_BUS | 3 | depends on IPACK_BUS && TTY |
4 | help | 4 | help |
5 | This driver supports the IPOCTAL serial port device for the IndustryPack bus. | 5 | This driver supports the IPOCTAL serial port device for the IndustryPack bus. |
6 | default n | 6 | default n |
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 576d53d92677..ab20a0851dd2 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c | |||
@@ -133,9 +133,9 @@ static int ipoctal_get_icount(struct tty_struct *tty, | |||
133 | return 0; | 133 | return 0; |
134 | } | 134 | } |
135 | 135 | ||
136 | static void ipoctal_irq_rx(struct ipoctal_channel *channel, | 136 | static void ipoctal_irq_rx(struct ipoctal_channel *channel, u8 sr) |
137 | struct tty_struct *tty, u8 sr) | ||
138 | { | 137 | { |
138 | struct tty_port *port = &channel->tty_port; | ||
139 | unsigned char value; | 139 | unsigned char value; |
140 | unsigned char flag = TTY_NORMAL; | 140 | unsigned char flag = TTY_NORMAL; |
141 | u8 isr; | 141 | u8 isr; |
@@ -149,7 +149,7 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel, | |||
149 | if (sr & SR_OVERRUN_ERROR) { | 149 | if (sr & SR_OVERRUN_ERROR) { |
150 | channel->stats.overrun_err++; | 150 | channel->stats.overrun_err++; |
151 | /* Overrun doesn't affect the current character*/ | 151 | /* Overrun doesn't affect the current character*/ |
152 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 152 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
153 | } | 153 | } |
154 | if (sr & SR_PARITY_ERROR) { | 154 | if (sr & SR_PARITY_ERROR) { |
155 | channel->stats.parity_err++; | 155 | channel->stats.parity_err++; |
@@ -165,7 +165,7 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel, | |||
165 | flag = TTY_BREAK; | 165 | flag = TTY_BREAK; |
166 | } | 166 | } |
167 | } | 167 | } |
168 | tty_insert_flip_char(tty, value, flag); | 168 | tty_insert_flip_char(port, value, flag); |
169 | 169 | ||
170 | /* Check if there are more characters in RX FIFO | 170 | /* Check if there are more characters in RX FIFO |
171 | * If there are more, the isr register for this channel | 171 | * If there are more, the isr register for this channel |
@@ -175,7 +175,7 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel, | |||
175 | sr = ioread8(&channel->regs->r.sr); | 175 | sr = ioread8(&channel->regs->r.sr); |
176 | } while (isr & channel->isr_rx_rdy_mask); | 176 | } while (isr & channel->isr_rx_rdy_mask); |
177 | 177 | ||
178 | tty_flip_buffer_push(tty); | 178 | tty_flip_buffer_push(port); |
179 | } | 179 | } |
180 | 180 | ||
181 | static void ipoctal_irq_tx(struct ipoctal_channel *channel) | 181 | static void ipoctal_irq_tx(struct ipoctal_channel *channel) |
@@ -208,15 +208,11 @@ static void ipoctal_irq_tx(struct ipoctal_channel *channel) | |||
208 | static void ipoctal_irq_channel(struct ipoctal_channel *channel) | 208 | static void ipoctal_irq_channel(struct ipoctal_channel *channel) |
209 | { | 209 | { |
210 | u8 isr, sr; | 210 | u8 isr, sr; |
211 | struct tty_struct *tty; | ||
212 | 211 | ||
213 | /* If there is no client, skip the check */ | 212 | /* If there is no client, skip the check */ |
214 | if (!atomic_read(&channel->open)) | 213 | if (!atomic_read(&channel->open)) |
215 | return; | 214 | return; |
216 | 215 | ||
217 | tty = tty_port_tty_get(&channel->tty_port); | ||
218 | if (!tty) | ||
219 | return; | ||
220 | /* The HW is organized in pair of channels. See which register we need | 216 | /* The HW is organized in pair of channels. See which register we need |
221 | * to read from */ | 217 | * to read from */ |
222 | isr = ioread8(&channel->block_regs->r.isr); | 218 | isr = ioread8(&channel->block_regs->r.isr); |
@@ -235,14 +231,13 @@ static void ipoctal_irq_channel(struct ipoctal_channel *channel) | |||
235 | 231 | ||
236 | /* RX data */ | 232 | /* RX data */ |
237 | if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) | 233 | if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) |
238 | ipoctal_irq_rx(channel, tty, sr); | 234 | ipoctal_irq_rx(channel, sr); |
239 | 235 | ||
240 | /* TX of each character */ | 236 | /* TX of each character */ |
241 | if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) | 237 | if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) |
242 | ipoctal_irq_tx(channel); | 238 | ipoctal_irq_tx(channel); |
243 | 239 | ||
244 | tty_flip_buffer_push(tty); | 240 | tty_flip_buffer_push(&channel->tty_port); |
245 | tty_kref_put(tty); | ||
246 | } | 241 | } |
247 | 242 | ||
248 | static irqreturn_t ipoctal_irq_handler(void *arg) | 243 | static irqreturn_t ipoctal_irq_handler(void *arg) |
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig index 86cd75a0e84d..ef661acdda17 100644 --- a/drivers/isdn/Kconfig +++ b/drivers/isdn/Kconfig | |||
@@ -22,6 +22,7 @@ if ISDN | |||
22 | 22 | ||
23 | menuconfig ISDN_I4L | 23 | menuconfig ISDN_I4L |
24 | tristate "Old ISDN4Linux (deprecated)" | 24 | tristate "Old ISDN4Linux (deprecated)" |
25 | depends on TTY | ||
25 | ---help--- | 26 | ---help--- |
26 | This driver allows you to use an ISDN adapter for networking | 27 | This driver allows you to use an ISDN adapter for networking |
27 | connections and as dialin/out device. The isdn-tty's have a built | 28 | connections and as dialin/out device. The isdn-tty's have a built |
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig index 15c3ffd9d860..f04686580040 100644 --- a/drivers/isdn/capi/Kconfig +++ b/drivers/isdn/capi/Kconfig | |||
@@ -18,6 +18,7 @@ config CAPI_TRACE | |||
18 | 18 | ||
19 | config ISDN_CAPI_MIDDLEWARE | 19 | config ISDN_CAPI_MIDDLEWARE |
20 | bool "CAPI2.0 Middleware support" | 20 | bool "CAPI2.0 Middleware support" |
21 | depends on TTY | ||
21 | help | 22 | help |
22 | This option will enhance the capabilities of the /dev/capi20 | 23 | This option will enhance the capabilities of the /dev/capi20 |
23 | interface. It will provide a means of moving a data connection, | 24 | interface. It will provide a means of moving a data connection, |
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig index b18a92c32184..dde5e09e6267 100644 --- a/drivers/isdn/gigaset/Kconfig +++ b/drivers/isdn/gigaset/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | menuconfig ISDN_DRV_GIGASET | 1 | menuconfig ISDN_DRV_GIGASET |
2 | tristate "Siemens Gigaset support" | 2 | tristate "Siemens Gigaset support" |
3 | depends on TTY | ||
3 | select CRC_CCITT | 4 | select CRC_CCITT |
4 | select BITREVERSE | 5 | select BITREVERSE |
5 | help | 6 | help |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 20b7e7a1190f..e2b539675b66 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -134,7 +134,7 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
134 | 134 | ||
135 | if (cs->port.count == 1) { | 135 | if (cs->port.count == 1) { |
136 | tty_port_tty_set(&cs->port, tty); | 136 | tty_port_tty_set(&cs->port, tty); |
137 | tty->low_latency = 1; | 137 | cs->port.low_latency = 1; |
138 | } | 138 | } |
139 | 139 | ||
140 | mutex_unlock(&cs->mutex); | 140 | mutex_unlock(&cs->mutex); |
@@ -546,16 +546,8 @@ void gigaset_if_free(struct cardstate *cs) | |||
546 | void gigaset_if_receive(struct cardstate *cs, | 546 | void gigaset_if_receive(struct cardstate *cs, |
547 | unsigned char *buffer, size_t len) | 547 | unsigned char *buffer, size_t len) |
548 | { | 548 | { |
549 | struct tty_struct *tty = tty_port_tty_get(&cs->port); | 549 | tty_insert_flip_string(&cs->port, buffer, len); |
550 | 550 | tty_flip_buffer_push(&cs->port); | |
551 | if (tty == NULL) { | ||
552 | gig_dbg(DEBUG_IF, "receive on closed device"); | ||
553 | return; | ||
554 | } | ||
555 | |||
556 | tty_insert_flip_string(tty, buffer, len); | ||
557 | tty_flip_buffer_push(tty); | ||
558 | tty_kref_put(tty); | ||
559 | } | 551 | } |
560 | EXPORT_SYMBOL_GPL(gigaset_if_receive); | 552 | EXPORT_SYMBOL_GPL(gigaset_if_receive); |
561 | 553 | ||
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig index eadc1cd34a20..b8611e3e5e74 100644 --- a/drivers/isdn/hardware/mISDN/Kconfig +++ b/drivers/isdn/hardware/mISDN/Kconfig | |||
@@ -76,6 +76,7 @@ config MISDN_NETJET | |||
76 | tristate "Support for NETJet cards" | 76 | tristate "Support for NETJet cards" |
77 | depends on MISDN | 77 | depends on MISDN |
78 | depends on PCI | 78 | depends on PCI |
79 | depends on TTY | ||
79 | select MISDN_IPAC | 80 | select MISDN_IPAC |
80 | select ISDN_HDLC | 81 | select ISDN_HDLC |
81 | select ISDN_I4L | 82 | select ISDN_I4L |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index e2a945ee9f05..b87d9e577be2 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -876,7 +876,7 @@ isdn_readbchan(int di, int channel, u_char *buf, u_char *fp, int len, wait_queue | |||
876 | * of the mapping (di,ch)<->minor, happen during the sleep? --he | 876 | * of the mapping (di,ch)<->minor, happen during the sleep? --he |
877 | */ | 877 | */ |
878 | int | 878 | int |
879 | isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | 879 | isdn_readbchan_tty(int di, int channel, struct tty_port *port, int cisco_hack) |
880 | { | 880 | { |
881 | int count; | 881 | int count; |
882 | int count_pull; | 882 | int count_pull; |
@@ -891,7 +891,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
891 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) | 891 | if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) |
892 | return 0; | 892 | return 0; |
893 | 893 | ||
894 | len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]); | 894 | len = tty_buffer_request_room(port, dev->drv[di]->rcvcount[channel]); |
895 | if (len == 0) | 895 | if (len == 0) |
896 | return len; | 896 | return len; |
897 | 897 | ||
@@ -912,7 +912,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
912 | while ((count_pull < skb->len) && (len > 0)) { | 912 | while ((count_pull < skb->len) && (len > 0)) { |
913 | /* push every character but the last to the tty buffer directly */ | 913 | /* push every character but the last to the tty buffer directly */ |
914 | if (count_put) | 914 | if (count_put) |
915 | tty_insert_flip_char(tty, last, TTY_NORMAL); | 915 | tty_insert_flip_char(port, last, TTY_NORMAL); |
916 | len--; | 916 | len--; |
917 | if (dev->drv[di]->DLEflag & DLEmask) { | 917 | if (dev->drv[di]->DLEflag & DLEmask) { |
918 | last = DLE; | 918 | last = DLE; |
@@ -940,7 +940,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
940 | } | 940 | } |
941 | count_put = count_pull; | 941 | count_put = count_pull; |
942 | if (count_put > 1) | 942 | if (count_put > 1) |
943 | tty_insert_flip_string(tty, skb->data, count_put - 1); | 943 | tty_insert_flip_string(port, skb->data, count_put - 1); |
944 | last = skb->data[count_put - 1]; | 944 | last = skb->data[count_put - 1]; |
945 | len -= count_put; | 945 | len -= count_put; |
946 | #ifdef CONFIG_ISDN_AUDIO | 946 | #ifdef CONFIG_ISDN_AUDIO |
@@ -952,16 +952,16 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
952 | * Now we can dequeue it. | 952 | * Now we can dequeue it. |
953 | */ | 953 | */ |
954 | if (cisco_hack) | 954 | if (cisco_hack) |
955 | tty_insert_flip_char(tty, last, 0xFF); | 955 | tty_insert_flip_char(port, last, 0xFF); |
956 | else | 956 | else |
957 | tty_insert_flip_char(tty, last, TTY_NORMAL); | 957 | tty_insert_flip_char(port, last, TTY_NORMAL); |
958 | #ifdef CONFIG_ISDN_AUDIO | 958 | #ifdef CONFIG_ISDN_AUDIO |
959 | ISDN_AUDIO_SKB_LOCK(skb) = 0; | 959 | ISDN_AUDIO_SKB_LOCK(skb) = 0; |
960 | #endif | 960 | #endif |
961 | skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); | 961 | skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); |
962 | dev_kfree_skb(skb); | 962 | dev_kfree_skb(skb); |
963 | } else { | 963 | } else { |
964 | tty_insert_flip_char(tty, last, TTY_NORMAL); | 964 | tty_insert_flip_char(port, last, TTY_NORMAL); |
965 | /* Not yet emptied this buff, so it | 965 | /* Not yet emptied this buff, so it |
966 | * must stay in the queue, for further calls | 966 | * must stay in the queue, for further calls |
967 | * but we pull off the data we got until now. | 967 | * but we pull off the data we got until now. |
diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h index 9a471f62e1d4..2260ef07ab9c 100644 --- a/drivers/isdn/i4l/isdn_common.h +++ b/drivers/isdn/i4l/isdn_common.h | |||
@@ -37,7 +37,7 @@ extern void isdn_timer_ctrl(int tf, int onoff); | |||
37 | extern void isdn_unexclusive_channel(int di, int ch); | 37 | extern void isdn_unexclusive_channel(int di, int ch); |
38 | extern int isdn_getnum(char **); | 38 | extern int isdn_getnum(char **); |
39 | extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); | 39 | extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); |
40 | extern int isdn_readbchan_tty(int, int, struct tty_struct *, int); | 40 | extern int isdn_readbchan_tty(int, int, struct tty_port *, int); |
41 | extern int isdn_get_free_channel(int, int, int, int, int, char *); | 41 | extern int isdn_get_free_channel(int, int, int, int, int, char *); |
42 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); | 42 | extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); |
43 | extern int register_isdn(isdn_if *i); | 43 | extern int register_isdn(isdn_if *i); |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index e09dc8a5e743..d8a7d8323414 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -60,18 +60,14 @@ static int si2bit[8] = | |||
60 | static int | 60 | static int |
61 | isdn_tty_try_read(modem_info *info, struct sk_buff *skb) | 61 | isdn_tty_try_read(modem_info *info, struct sk_buff *skb) |
62 | { | 62 | { |
63 | struct tty_port *port = &info->port; | ||
63 | int c; | 64 | int c; |
64 | int len; | 65 | int len; |
65 | struct tty_struct *tty; | ||
66 | char last; | 66 | char last; |
67 | 67 | ||
68 | if (!info->online) | 68 | if (!info->online) |
69 | return 0; | 69 | return 0; |
70 | 70 | ||
71 | tty = info->port.tty; | ||
72 | if (!tty) | ||
73 | return 0; | ||
74 | |||
75 | if (!(info->mcr & UART_MCR_RTS)) | 71 | if (!(info->mcr & UART_MCR_RTS)) |
76 | return 0; | 72 | return 0; |
77 | 73 | ||
@@ -81,7 +77,7 @@ isdn_tty_try_read(modem_info *info, struct sk_buff *skb) | |||
81 | #endif | 77 | #endif |
82 | ; | 78 | ; |
83 | 79 | ||
84 | c = tty_buffer_request_room(tty, len); | 80 | c = tty_buffer_request_room(port, len); |
85 | if (c < len) | 81 | if (c < len) |
86 | return 0; | 82 | return 0; |
87 | 83 | ||
@@ -91,25 +87,25 @@ isdn_tty_try_read(modem_info *info, struct sk_buff *skb) | |||
91 | unsigned char *dp = skb->data; | 87 | unsigned char *dp = skb->data; |
92 | while (--l) { | 88 | while (--l) { |
93 | if (*dp == DLE) | 89 | if (*dp == DLE) |
94 | tty_insert_flip_char(tty, DLE, 0); | 90 | tty_insert_flip_char(port, DLE, 0); |
95 | tty_insert_flip_char(tty, *dp++, 0); | 91 | tty_insert_flip_char(port, *dp++, 0); |
96 | } | 92 | } |
97 | if (*dp == DLE) | 93 | if (*dp == DLE) |
98 | tty_insert_flip_char(tty, DLE, 0); | 94 | tty_insert_flip_char(port, DLE, 0); |
99 | last = *dp; | 95 | last = *dp; |
100 | } else { | 96 | } else { |
101 | #endif | 97 | #endif |
102 | if (len > 1) | 98 | if (len > 1) |
103 | tty_insert_flip_string(tty, skb->data, len - 1); | 99 | tty_insert_flip_string(port, skb->data, len - 1); |
104 | last = skb->data[len - 1]; | 100 | last = skb->data[len - 1]; |
105 | #ifdef CONFIG_ISDN_AUDIO | 101 | #ifdef CONFIG_ISDN_AUDIO |
106 | } | 102 | } |
107 | #endif | 103 | #endif |
108 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) | 104 | if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP) |
109 | tty_insert_flip_char(tty, last, 0xFF); | 105 | tty_insert_flip_char(port, last, 0xFF); |
110 | else | 106 | else |
111 | tty_insert_flip_char(tty, last, TTY_NORMAL); | 107 | tty_insert_flip_char(port, last, TTY_NORMAL); |
112 | tty_flip_buffer_push(tty); | 108 | tty_flip_buffer_push(port); |
113 | kfree_skb(skb); | 109 | kfree_skb(skb); |
114 | 110 | ||
115 | return 1; | 111 | return 1; |
@@ -126,7 +122,6 @@ isdn_tty_readmodem(void) | |||
126 | int midx; | 122 | int midx; |
127 | int i; | 123 | int i; |
128 | int r; | 124 | int r; |
129 | struct tty_struct *tty; | ||
130 | modem_info *info; | 125 | modem_info *info; |
131 | 126 | ||
132 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) { | 127 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) { |
@@ -144,20 +139,21 @@ isdn_tty_readmodem(void) | |||
144 | if ((info->vonline & 1) && (info->emu.vpar[1])) | 139 | if ((info->vonline & 1) && (info->emu.vpar[1])) |
145 | isdn_audio_eval_silence(info); | 140 | isdn_audio_eval_silence(info); |
146 | #endif | 141 | #endif |
147 | tty = info->port.tty; | 142 | if (info->mcr & UART_MCR_RTS) { |
148 | if (tty) { | 143 | /* CISCO AsyncPPP Hack */ |
149 | if (info->mcr & UART_MCR_RTS) { | 144 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) |
150 | /* CISCO AsyncPPP Hack */ | 145 | r = isdn_readbchan_tty(info->isdn_driver, |
151 | if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP)) | 146 | info->isdn_channel, |
152 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0); | 147 | &info->port, 0); |
153 | else | 148 | else |
154 | r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1); | 149 | r = isdn_readbchan_tty(info->isdn_driver, |
155 | if (r) | 150 | info->isdn_channel, |
156 | tty_flip_buffer_push(tty); | 151 | &info->port, 1); |
157 | } else | 152 | if (r) |
158 | r = 1; | 153 | tty_flip_buffer_push(&info->port); |
159 | } else | 154 | } else |
160 | r = 1; | 155 | r = 1; |
156 | |||
161 | if (r) { | 157 | if (r) { |
162 | info->rcvsched = 0; | 158 | info->rcvsched = 0; |
163 | resched = 1; | 159 | resched = 1; |
@@ -2229,7 +2225,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c) | |||
2229 | void | 2225 | void |
2230 | isdn_tty_at_cout(char *msg, modem_info *info) | 2226 | isdn_tty_at_cout(char *msg, modem_info *info) |
2231 | { | 2227 | { |
2232 | struct tty_struct *tty; | 2228 | struct tty_port *port = &info->port; |
2233 | atemu *m = &info->emu; | 2229 | atemu *m = &info->emu; |
2234 | char *p; | 2230 | char *p; |
2235 | char c; | 2231 | char c; |
@@ -2246,15 +2242,14 @@ isdn_tty_at_cout(char *msg, modem_info *info) | |||
2246 | l = strlen(msg); | 2242 | l = strlen(msg); |
2247 | 2243 | ||
2248 | spin_lock_irqsave(&info->readlock, flags); | 2244 | spin_lock_irqsave(&info->readlock, flags); |
2249 | tty = info->port.tty; | 2245 | if (port->flags & ASYNC_CLOSING) { |
2250 | if ((info->port.flags & ASYNC_CLOSING) || (!tty)) { | ||
2251 | spin_unlock_irqrestore(&info->readlock, flags); | 2246 | spin_unlock_irqrestore(&info->readlock, flags); |
2252 | return; | 2247 | return; |
2253 | } | 2248 | } |
2254 | 2249 | ||
2255 | /* use queue instead of direct, if online and */ | 2250 | /* use queue instead of direct, if online and */ |
2256 | /* data is in queue or buffer is full */ | 2251 | /* data is in queue or buffer is full */ |
2257 | if (info->online && ((tty_buffer_request_room(tty, l) < l) || | 2252 | if (info->online && ((tty_buffer_request_room(port, l) < l) || |
2258 | !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { | 2253 | !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) { |
2259 | skb = alloc_skb(l, GFP_ATOMIC); | 2254 | skb = alloc_skb(l, GFP_ATOMIC); |
2260 | if (!skb) { | 2255 | if (!skb) { |
@@ -2285,7 +2280,7 @@ isdn_tty_at_cout(char *msg, modem_info *info) | |||
2285 | if (skb) { | 2280 | if (skb) { |
2286 | *sp++ = c; | 2281 | *sp++ = c; |
2287 | } else { | 2282 | } else { |
2288 | if (tty_insert_flip_char(tty, c, TTY_NORMAL) == 0) | 2283 | if (tty_insert_flip_char(port, c, TTY_NORMAL) == 0) |
2289 | break; | 2284 | break; |
2290 | } | 2285 | } |
2291 | } | 2286 | } |
@@ -2299,7 +2294,7 @@ isdn_tty_at_cout(char *msg, modem_info *info) | |||
2299 | 2294 | ||
2300 | } else { | 2295 | } else { |
2301 | spin_unlock_irqrestore(&info->readlock, flags); | 2296 | spin_unlock_irqrestore(&info->readlock, flags); |
2302 | tty_flip_buffer_push(tty); | 2297 | tty_flip_buffer_push(port); |
2303 | } | 2298 | } |
2304 | } | 2299 | } |
2305 | 2300 | ||
diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index 6cdcdb0d3d58..89875ea19ade 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config LGUEST | 1 | config LGUEST |
2 | tristate "Linux hypervisor example code" | 2 | tristate "Linux hypervisor example code" |
3 | depends on X86_32 && EVENTFD | 3 | depends on X86_32 && EVENTFD && TTY |
4 | select HVC_DRIVER | 4 | select HVC_DRIVER |
5 | ---help--- | 5 | ---help--- |
6 | This is a very simple module which allows you to run | 6 | This is a very simple module which allows you to run |
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig index ea1e6545df36..f359be7e9dd9 100644 --- a/drivers/media/radio/wl128x/Kconfig +++ b/drivers/media/radio/wl128x/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | menu "Texas Instruments WL128x FM driver (ST based)" | 4 | menu "Texas Instruments WL128x FM driver (ST based)" |
5 | config RADIO_WL128X | 5 | config RADIO_WL128X |
6 | tristate "Texas Instruments WL128x FM Radio" | 6 | tristate "Texas Instruments WL128x FM Radio" |
7 | depends on VIDEO_V4L2 && RFKILL && GPIOLIB | 7 | depends on VIDEO_V4L2 && RFKILL && GPIOLIB && TTY |
8 | select TI_ST if NET | 8 | select TI_ST if NET |
9 | help | 9 | help |
10 | Choose Y here if you have this FM radio chip. | 10 | Choose Y here if you have this FM radio chip. |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 8f59d88897e7..668a5822ab4e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -127,7 +127,7 @@ config PHANTOM | |||
127 | 127 | ||
128 | config INTEL_MID_PTI | 128 | config INTEL_MID_PTI |
129 | tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" | 129 | tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard" |
130 | depends on PCI | 130 | depends on PCI && TTY |
131 | default n | 131 | default n |
132 | help | 132 | help |
133 | The PTI (Parallel Trace Interface) driver directs | 133 | The PTI (Parallel Trace Interface) driver directs |
diff --git a/drivers/misc/ti-st/Kconfig b/drivers/misc/ti-st/Kconfig index abb5de1afce3..f34dcc514730 100644 --- a/drivers/misc/ti-st/Kconfig +++ b/drivers/misc/ti-st/Kconfig | |||
@@ -5,7 +5,7 @@ | |||
5 | menu "Texas Instruments shared transport line discipline" | 5 | menu "Texas Instruments shared transport line discipline" |
6 | config TI_ST | 6 | config TI_ST |
7 | tristate "Shared transport core driver" | 7 | tristate "Shared transport core driver" |
8 | depends on NET && GPIOLIB | 8 | depends on NET && GPIOLIB && TTY |
9 | select FW_LOADER | 9 | select FW_LOADER |
10 | help | 10 | help |
11 | This enables the shared transport core driver for TI | 11 | This enables the shared transport core driver for TI |
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index 3b1f783bf924..5562308699bc 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig | |||
@@ -52,6 +52,7 @@ config MMC_BLOCK_BOUNCE | |||
52 | 52 | ||
53 | config SDIO_UART | 53 | config SDIO_UART |
54 | tristate "SDIO UART/GPS class support" | 54 | tristate "SDIO UART/GPS class support" |
55 | depends on TTY | ||
55 | help | 56 | help |
56 | SDIO function driver for SDIO cards that implements the UART | 57 | SDIO function driver for SDIO cards that implements the UART |
57 | class, as well as the GPS class which appears like a UART. | 58 | class, as well as the GPS class which appears like a UART. |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index bd57a11acc79..c931dfe6a59c 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -381,7 +381,6 @@ static void sdio_uart_stop_rx(struct sdio_uart_port *port) | |||
381 | static void sdio_uart_receive_chars(struct sdio_uart_port *port, | 381 | static void sdio_uart_receive_chars(struct sdio_uart_port *port, |
382 | unsigned int *status) | 382 | unsigned int *status) |
383 | { | 383 | { |
384 | struct tty_struct *tty = tty_port_tty_get(&port->port); | ||
385 | unsigned int ch, flag; | 384 | unsigned int ch, flag; |
386 | int max_count = 256; | 385 | int max_count = 256; |
387 | 386 | ||
@@ -418,23 +417,19 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port, | |||
418 | } | 417 | } |
419 | 418 | ||
420 | if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) | 419 | if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) |
421 | if (tty) | 420 | tty_insert_flip_char(&port->port, ch, flag); |
422 | tty_insert_flip_char(tty, ch, flag); | ||
423 | 421 | ||
424 | /* | 422 | /* |
425 | * Overrun is special. Since it's reported immediately, | 423 | * Overrun is special. Since it's reported immediately, |
426 | * it doesn't affect the current character. | 424 | * it doesn't affect the current character. |
427 | */ | 425 | */ |
428 | if (*status & ~port->ignore_status_mask & UART_LSR_OE) | 426 | if (*status & ~port->ignore_status_mask & UART_LSR_OE) |
429 | if (tty) | 427 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
430 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
431 | 428 | ||
432 | *status = sdio_in(port, UART_LSR); | 429 | *status = sdio_in(port, UART_LSR); |
433 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 430 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
434 | if (tty) { | 431 | |
435 | tty_flip_buffer_push(tty); | 432 | tty_flip_buffer_push(&port->port); |
436 | tty_kref_put(tty); | ||
437 | } | ||
438 | } | 433 | } |
439 | 434 | ||
440 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) | 435 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) |
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig index abf4d7a9dcce..60c2142373c9 100644 --- a/drivers/net/caif/Kconfig +++ b/drivers/net/caif/Kconfig | |||
@@ -6,7 +6,7 @@ comment "CAIF transport drivers" | |||
6 | 6 | ||
7 | config CAIF_TTY | 7 | config CAIF_TTY |
8 | tristate "CAIF TTY transport driver" | 8 | tristate "CAIF TTY transport driver" |
9 | depends on CAIF | 9 | depends on CAIF && TTY |
10 | default n | 10 | default n |
11 | ---help--- | 11 | ---help--- |
12 | The CAIF TTY transport driver is a Line Discipline (ldisc) | 12 | The CAIF TTY transport driver is a Line Discipline (ldisc) |
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index 5de74e762021..666891a9a248 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c | |||
@@ -91,7 +91,7 @@ static inline void update_tty_status(struct ser_device *ser) | |||
91 | ser->tty->hw_stopped << 4 | | 91 | ser->tty->hw_stopped << 4 | |
92 | ser->tty->flow_stopped << 3 | | 92 | ser->tty->flow_stopped << 3 | |
93 | ser->tty->packet << 2 | | 93 | ser->tty->packet << 2 | |
94 | ser->tty->low_latency << 1 | | 94 | ser->tty->port->low_latency << 1 | |
95 | ser->tty->warned; | 95 | ser->tty->warned; |
96 | } | 96 | } |
97 | static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) | 97 | static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty) |
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 1cca19f1c490..9862b2e07644 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
@@ -11,6 +11,7 @@ config CAN_VCAN | |||
11 | 11 | ||
12 | config CAN_SLCAN | 12 | config CAN_SLCAN |
13 | tristate "Serial / USB serial CAN Adaptors (slcan)" | 13 | tristate "Serial / USB serial CAN Adaptors (slcan)" |
14 | depends on TTY | ||
14 | ---help--- | 15 | ---help--- |
15 | CAN driver for several 'low cost' CAN interfaces that are attached | 16 | CAN driver for several 'low cost' CAN interfaces that are attached |
16 | via serial lines or via USB-to-serial adapters using the LAWICEL | 17 | via serial lines or via USB-to-serial adapters using the LAWICEL |
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig index 95dbcfdf131d..bf5e59687680 100644 --- a/drivers/net/hamradio/Kconfig +++ b/drivers/net/hamradio/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config MKISS | 1 | config MKISS |
2 | tristate "Serial port KISS driver" | 2 | tristate "Serial port KISS driver" |
3 | depends on AX25 | 3 | depends on AX25 && TTY |
4 | select CRC16 | 4 | select CRC16 |
5 | ---help--- | 5 | ---help--- |
6 | KISS is a protocol used for the exchange of data between a computer | 6 | KISS is a protocol used for the exchange of data between a computer |
@@ -18,7 +18,7 @@ config MKISS | |||
18 | 18 | ||
19 | config 6PACK | 19 | config 6PACK |
20 | tristate "Serial port 6PACK driver" | 20 | tristate "Serial port 6PACK driver" |
21 | depends on AX25 | 21 | depends on AX25 && TTY |
22 | ---help--- | 22 | ---help--- |
23 | 6pack is a transmission protocol for the data exchange between your | 23 | 6pack is a transmission protocol for the data exchange between your |
24 | PC and your TNC (the Terminal Node Controller acts as a kind of | 24 | PC and your TNC (the Terminal Node Controller acts as a kind of |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 59e9d9e1fd0f..2a30193d0d50 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -5,7 +5,7 @@ comment "SIR device drivers" | |||
5 | 5 | ||
6 | config IRTTY_SIR | 6 | config IRTTY_SIR |
7 | tristate "IrTTY (uses Linux serial driver)" | 7 | tristate "IrTTY (uses Linux serial driver)" |
8 | depends on IRDA | 8 | depends on IRDA && TTY |
9 | help | 9 | help |
10 | Say Y here if you want to build support for the IrTTY line | 10 | Say Y here if you want to build support for the IrTTY line |
11 | discipline. To compile it as a module, choose M here: the module | 11 | discipline. To compile it as a module, choose M here: the module |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 6e4d4b62c9a8..a41267197839 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -210,7 +210,7 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t | |||
210 | * been received, which can now be decapsulated and delivered for | 210 | * been received, which can now be decapsulated and delivered for |
211 | * further processing | 211 | * further processing |
212 | * | 212 | * |
213 | * calling context depends on underlying driver and tty->low_latency! | 213 | * calling context depends on underlying driver and tty->port->low_latency! |
214 | * for example (low_latency: 1 / 0): | 214 | * for example (low_latency: 1 / 0): |
215 | * serial.c: uart-interrupt / softint | 215 | * serial.c: uart-interrupt / softint |
216 | * usbserial: urb-complete-interrupt / softint | 216 | * usbserial: urb-complete-interrupt / softint |
diff --git a/drivers/net/ppp/Kconfig b/drivers/net/ppp/Kconfig index 278dea0c4c98..1373c6d7278d 100644 --- a/drivers/net/ppp/Kconfig +++ b/drivers/net/ppp/Kconfig | |||
@@ -147,6 +147,7 @@ config PPPOL2TP | |||
147 | Support for PPP-over-L2TP socket family. L2TP is a protocol | 147 | Support for PPP-over-L2TP socket family. L2TP is a protocol |
148 | used by ISPs and enterprises to tunnel PPP traffic over UDP | 148 | used by ISPs and enterprises to tunnel PPP traffic over UDP |
149 | tunnels. L2TP is replacing PPTP for VPN uses. | 149 | tunnels. L2TP is replacing PPTP for VPN uses. |
150 | if TTY | ||
150 | 151 | ||
151 | config PPP_ASYNC | 152 | config PPP_ASYNC |
152 | tristate "PPP support for async serial ports" | 153 | tristate "PPP support for async serial ports" |
@@ -172,4 +173,6 @@ config PPP_SYNC_TTY | |||
172 | 173 | ||
173 | To compile this driver as a module, choose M here. | 174 | To compile this driver as a module, choose M here. |
174 | 175 | ||
176 | endif # TTY | ||
177 | |||
175 | endif # PPP | 178 | endif # PPP |
diff --git a/drivers/net/slip/Kconfig b/drivers/net/slip/Kconfig index 211b160e4e9c..48e68714eef3 100644 --- a/drivers/net/slip/Kconfig +++ b/drivers/net/slip/Kconfig | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | config SLIP | 5 | config SLIP |
6 | tristate "SLIP (serial line) support" | 6 | tristate "SLIP (serial line) support" |
7 | depends on TTY | ||
7 | ---help--- | 8 | ---help--- |
8 | Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to | 9 | Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to |
9 | connect to your Internet service provider or to connect to some | 10 | connect to your Internet service provider or to connect to some |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 3a44a5d7bf9e..da92ed3797aa 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -443,7 +443,7 @@ config USB_NET_QMI_WWAN | |||
443 | 443 | ||
444 | config USB_HSO | 444 | config USB_HSO |
445 | tristate "Option USB High Speed Mobile Devices" | 445 | tristate "Option USB High Speed Mobile Devices" |
446 | depends on USB && RFKILL | 446 | depends on USB && RFKILL && TTY |
447 | default n | 447 | default n |
448 | help | 448 | help |
449 | Choose this option if you have an Option HSDPA/HSUPA card. | 449 | Choose this option if you have an Option HSDPA/HSUPA card. |
@@ -491,7 +491,7 @@ config USB_SIERRA_NET | |||
491 | 491 | ||
492 | config USB_VL600 | 492 | config USB_VL600 |
493 | tristate "LG VL600 modem dongle" | 493 | tristate "LG VL600 modem dongle" |
494 | depends on USB_NET_CDCETHER | 494 | depends on USB_NET_CDCETHER && TTY |
495 | select USB_ACM | 495 | select USB_ACM |
496 | help | 496 | help |
497 | Select this if you want to use an LG Electronics 4G/LTE usb modem | 497 | Select this if you want to use an LG Electronics 4G/LTE usb modem |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 41e5dfb5ee64..e2dd3249b6bd 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -2035,25 +2035,23 @@ static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) | |||
2035 | tty = tty_port_tty_get(&serial->port); | 2035 | tty = tty_port_tty_get(&serial->port); |
2036 | 2036 | ||
2037 | /* Push data to tty */ | 2037 | /* Push data to tty */ |
2038 | if (tty) { | 2038 | write_length_remaining = urb->actual_length - |
2039 | write_length_remaining = urb->actual_length - | 2039 | serial->curr_rx_urb_offset; |
2040 | serial->curr_rx_urb_offset; | 2040 | D1("data to push to tty"); |
2041 | D1("data to push to tty"); | 2041 | while (write_length_remaining) { |
2042 | while (write_length_remaining) { | 2042 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { |
2043 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 2043 | tty_kref_put(tty); |
2044 | tty_kref_put(tty); | 2044 | return -1; |
2045 | return -1; | ||
2046 | } | ||
2047 | curr_write_len = tty_insert_flip_string | ||
2048 | (tty, urb->transfer_buffer + | ||
2049 | serial->curr_rx_urb_offset, | ||
2050 | write_length_remaining); | ||
2051 | serial->curr_rx_urb_offset += curr_write_len; | ||
2052 | write_length_remaining -= curr_write_len; | ||
2053 | tty_flip_buffer_push(tty); | ||
2054 | } | 2045 | } |
2055 | tty_kref_put(tty); | 2046 | curr_write_len = tty_insert_flip_string(&serial->port, |
2047 | urb->transfer_buffer + serial->curr_rx_urb_offset, | ||
2048 | write_length_remaining); | ||
2049 | serial->curr_rx_urb_offset += curr_write_len; | ||
2050 | write_length_remaining -= curr_write_len; | ||
2051 | tty_flip_buffer_push(&serial->port); | ||
2056 | } | 2052 | } |
2053 | tty_kref_put(tty); | ||
2054 | |||
2057 | if (write_length_remaining == 0) { | 2055 | if (write_length_remaining == 0) { |
2058 | serial->curr_rx_urb_offset = 0; | 2056 | serial->curr_rx_urb_offset = 0; |
2059 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; | 2057 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; |
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig index 13daec88d918..94e234975c61 100644 --- a/drivers/net/wan/Kconfig +++ b/drivers/net/wan/Kconfig | |||
@@ -375,7 +375,7 @@ config LAPBETHER | |||
375 | 375 | ||
376 | config X25_ASY | 376 | config X25_ASY |
377 | tristate "X.25 async driver" | 377 | tristate "X.25 async driver" |
378 | depends on LAPB && X25 | 378 | depends on LAPB && X25 && TTY |
379 | ---help--- | 379 | ---help--- |
380 | Send and receive X.25 frames over regular asynchronous serial | 380 | Send and receive X.25 frames over regular asynchronous serial |
381 | lines such as telephone lines equipped with ordinary modems. | 381 | lines such as telephone lines equipped with ordinary modems. |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index ef6169adb845..1b8bdb7e9bf4 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -63,6 +63,7 @@ enum parport_pc_pci_cards { | |||
63 | timedia_9079b, | 63 | timedia_9079b, |
64 | timedia_9079c, | 64 | timedia_9079c, |
65 | wch_ch353_2s1p, | 65 | wch_ch353_2s1p, |
66 | sunix_2s1p, | ||
66 | }; | 67 | }; |
67 | 68 | ||
68 | /* each element directly indexed from enum list, above */ | 69 | /* each element directly indexed from enum list, above */ |
@@ -148,8 +149,12 @@ static struct parport_pc_pci cards[] = { | |||
148 | /* timedia_9079b */ { 1, { { 2, 3 }, } }, | 149 | /* timedia_9079b */ { 1, { { 2, 3 }, } }, |
149 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, | 150 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, |
150 | /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, | 151 | /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, |
152 | /* sunix_2s1p */ { 1, { { 3, -1 }, } }, | ||
151 | }; | 153 | }; |
152 | 154 | ||
155 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 | ||
156 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 | ||
157 | |||
153 | static struct pci_device_id parport_serial_pci_tbl[] = { | 158 | static struct pci_device_id parport_serial_pci_tbl[] = { |
154 | /* PCI cards */ | 159 | /* PCI cards */ |
155 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L, | 160 | { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L, |
@@ -246,8 +251,18 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
246 | { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, | 251 | { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, |
247 | { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, | 252 | { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, |
248 | { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, | 253 | { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, |
254 | |||
249 | /* WCH CARDS */ | 255 | /* WCH CARDS */ |
250 | { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, | 256 | { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, |
257 | |||
258 | /* | ||
259 | * More SUNIX variations. At least one of these has part number | ||
260 | * '5079A but subdevice 0x102. That board reports 0x0708 as | ||
261 | * its PCI Class. | ||
262 | */ | ||
263 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, | ||
264 | 0x0102, 0, 0, sunix_2s1p }, | ||
265 | |||
251 | { 0, } /* terminate list */ | 266 | { 0, } /* terminate list */ |
252 | }; | 267 | }; |
253 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); | 268 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); |
@@ -470,6 +485,12 @@ static struct pciserial_board pci_parport_serial_boards[] = { | |||
470 | .base_baud = 115200, | 485 | .base_baud = 115200, |
471 | .uart_offset = 8, | 486 | .uart_offset = 8, |
472 | }, | 487 | }, |
488 | [sunix_2s1p] = { | ||
489 | .flags = FL_BASE0|FL_BASE_BARS, | ||
490 | .num_ports = 2, | ||
491 | .base_baud = 921600, | ||
492 | .uart_offset = 8, | ||
493 | }, | ||
473 | }; | 494 | }; |
474 | 495 | ||
475 | struct parport_serial_private { | 496 | struct parport_serial_private { |
diff --git a/drivers/pps/clients/Kconfig b/drivers/pps/clients/Kconfig index 445197d4a8c4..6efd9b60d8ff 100644 --- a/drivers/pps/clients/Kconfig +++ b/drivers/pps/clients/Kconfig | |||
@@ -17,7 +17,7 @@ config PPS_CLIENT_KTIMER | |||
17 | 17 | ||
18 | config PPS_CLIENT_LDISC | 18 | config PPS_CLIENT_LDISC |
19 | tristate "PPS line discipline" | 19 | tristate "PPS line discipline" |
20 | depends on PPS | 20 | depends on PPS && TTY |
21 | help | 21 | help |
22 | If you say yes here you get support for a PPS source connected | 22 | If you say yes here you get support for a PPS source connected |
23 | with the CD (Carrier Detect) pin of your serial port. | 23 | with the CD (Carrier Detect) pin of your serial port. |
diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c index 79451f2dea6a..73bd3bb4d93b 100644 --- a/drivers/pps/clients/pps-ldisc.c +++ b/drivers/pps/clients/pps-ldisc.c | |||
@@ -25,18 +25,27 @@ | |||
25 | #include <linux/serial_core.h> | 25 | #include <linux/serial_core.h> |
26 | #include <linux/tty.h> | 26 | #include <linux/tty.h> |
27 | #include <linux/pps_kernel.h> | 27 | #include <linux/pps_kernel.h> |
28 | #include <linux/bug.h> | ||
28 | 29 | ||
29 | #define PPS_TTY_MAGIC 0x0001 | 30 | #define PPS_TTY_MAGIC 0x0001 |
30 | 31 | ||
31 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, | 32 | static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status) |
32 | struct pps_event_time *ts) | ||
33 | { | 33 | { |
34 | struct pps_device *pps = (struct pps_device *)tty->disc_data; | 34 | struct pps_device *pps; |
35 | struct pps_event_time ts; | ||
36 | |||
37 | pps_get_ts(&ts); | ||
35 | 38 | ||
36 | BUG_ON(pps == NULL); | 39 | pps = pps_lookup_dev(tty); |
40 | /* | ||
41 | * This should never fail, but the ldisc locking is very | ||
42 | * convoluted, so don't crash just in case. | ||
43 | */ | ||
44 | if (WARN_ON_ONCE(pps == NULL)) | ||
45 | return; | ||
37 | 46 | ||
38 | /* Now do the PPS event report */ | 47 | /* Now do the PPS event report */ |
39 | pps_event(pps, ts, status ? PPS_CAPTUREASSERT : | 48 | pps_event(pps, &ts, status ? PPS_CAPTUREASSERT : |
40 | PPS_CAPTURECLEAR, NULL); | 49 | PPS_CAPTURECLEAR, NULL); |
41 | 50 | ||
42 | dev_dbg(pps->dev, "PPS %s at %lu\n", | 51 | dev_dbg(pps->dev, "PPS %s at %lu\n", |
@@ -67,9 +76,9 @@ static int pps_tty_open(struct tty_struct *tty) | |||
67 | pr_err("cannot register PPS source \"%s\"\n", info.path); | 76 | pr_err("cannot register PPS source \"%s\"\n", info.path); |
68 | return -ENOMEM; | 77 | return -ENOMEM; |
69 | } | 78 | } |
70 | tty->disc_data = pps; | 79 | pps->lookup_cookie = tty; |
71 | 80 | ||
72 | /* Should open N_TTY ldisc too */ | 81 | /* Now open the base class N_TTY ldisc */ |
73 | ret = alias_n_tty_open(tty); | 82 | ret = alias_n_tty_open(tty); |
74 | if (ret < 0) { | 83 | if (ret < 0) { |
75 | pr_err("cannot open tty ldisc \"%s\"\n", info.path); | 84 | pr_err("cannot open tty ldisc \"%s\"\n", info.path); |
@@ -81,7 +90,6 @@ static int pps_tty_open(struct tty_struct *tty) | |||
81 | return 0; | 90 | return 0; |
82 | 91 | ||
83 | err_unregister: | 92 | err_unregister: |
84 | tty->disc_data = NULL; | ||
85 | pps_unregister_source(pps); | 93 | pps_unregister_source(pps); |
86 | return ret; | 94 | return ret; |
87 | } | 95 | } |
@@ -90,11 +98,13 @@ static void (*alias_n_tty_close)(struct tty_struct *tty); | |||
90 | 98 | ||
91 | static void pps_tty_close(struct tty_struct *tty) | 99 | static void pps_tty_close(struct tty_struct *tty) |
92 | { | 100 | { |
93 | struct pps_device *pps = (struct pps_device *)tty->disc_data; | 101 | struct pps_device *pps = pps_lookup_dev(tty); |
94 | 102 | ||
95 | alias_n_tty_close(tty); | 103 | alias_n_tty_close(tty); |
96 | 104 | ||
97 | tty->disc_data = NULL; | 105 | if (WARN_ON(!pps)) |
106 | return; | ||
107 | |||
98 | dev_info(pps->dev, "removed\n"); | 108 | dev_info(pps->dev, "removed\n"); |
99 | pps_unregister_source(pps); | 109 | pps_unregister_source(pps); |
100 | } | 110 | } |
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 2420d5af0583..6437703eb10f 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c | |||
@@ -247,12 +247,15 @@ static int pps_cdev_open(struct inode *inode, struct file *file) | |||
247 | struct pps_device *pps = container_of(inode->i_cdev, | 247 | struct pps_device *pps = container_of(inode->i_cdev, |
248 | struct pps_device, cdev); | 248 | struct pps_device, cdev); |
249 | file->private_data = pps; | 249 | file->private_data = pps; |
250 | 250 | kobject_get(&pps->dev->kobj); | |
251 | return 0; | 251 | return 0; |
252 | } | 252 | } |
253 | 253 | ||
254 | static int pps_cdev_release(struct inode *inode, struct file *file) | 254 | static int pps_cdev_release(struct inode *inode, struct file *file) |
255 | { | 255 | { |
256 | struct pps_device *pps = container_of(inode->i_cdev, | ||
257 | struct pps_device, cdev); | ||
258 | kobject_put(&pps->dev->kobj); | ||
256 | return 0; | 259 | return 0; |
257 | } | 260 | } |
258 | 261 | ||
@@ -274,8 +277,10 @@ static void pps_device_destruct(struct device *dev) | |||
274 | { | 277 | { |
275 | struct pps_device *pps = dev_get_drvdata(dev); | 278 | struct pps_device *pps = dev_get_drvdata(dev); |
276 | 279 | ||
277 | /* release id here to protect others from using it while it's | 280 | cdev_del(&pps->cdev); |
278 | * still in use */ | 281 | |
282 | /* Now we can release the ID for re-use */ | ||
283 | pr_debug("deallocating pps%d\n", pps->id); | ||
279 | mutex_lock(&pps_idr_lock); | 284 | mutex_lock(&pps_idr_lock); |
280 | idr_remove(&pps_idr, pps->id); | 285 | idr_remove(&pps_idr, pps->id); |
281 | mutex_unlock(&pps_idr_lock); | 286 | mutex_unlock(&pps_idr_lock); |
@@ -332,6 +337,7 @@ int pps_register_cdev(struct pps_device *pps) | |||
332 | goto del_cdev; | 337 | goto del_cdev; |
333 | } | 338 | } |
334 | 339 | ||
340 | /* Override the release function with our own */ | ||
335 | pps->dev->release = pps_device_destruct; | 341 | pps->dev->release = pps_device_destruct; |
336 | 342 | ||
337 | pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, | 343 | pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, |
@@ -352,11 +358,44 @@ free_idr: | |||
352 | 358 | ||
353 | void pps_unregister_cdev(struct pps_device *pps) | 359 | void pps_unregister_cdev(struct pps_device *pps) |
354 | { | 360 | { |
361 | pr_debug("unregistering pps%d\n", pps->id); | ||
362 | pps->lookup_cookie = NULL; | ||
355 | device_destroy(pps_class, pps->dev->devt); | 363 | device_destroy(pps_class, pps->dev->devt); |
356 | cdev_del(&pps->cdev); | ||
357 | } | 364 | } |
358 | 365 | ||
359 | /* | 366 | /* |
367 | * Look up a pps device by magic cookie. | ||
368 | * The cookie is usually a pointer to some enclosing device, but this | ||
369 | * code doesn't care; you should never be dereferencing it. | ||
370 | * | ||
371 | * This is a bit of a kludge that is currently used only by the PPS | ||
372 | * serial line discipline. It may need to be tweaked when a second user | ||
373 | * is found. | ||
374 | * | ||
375 | * There is no function interface for setting the lookup_cookie field. | ||
376 | * It's initialized to NULL when the pps device is created, and if a | ||
377 | * client wants to use it, just fill it in afterward. | ||
378 | * | ||
379 | * The cookie is automatically set to NULL in pps_unregister_source() | ||
380 | * so that it will not be used again, even if the pps device cannot | ||
381 | * be removed from the idr due to pending references holding the minor | ||
382 | * number in use. | ||
383 | */ | ||
384 | struct pps_device *pps_lookup_dev(void const *cookie) | ||
385 | { | ||
386 | struct pps_device *pps; | ||
387 | unsigned id; | ||
388 | |||
389 | rcu_read_lock(); | ||
390 | idr_for_each_entry(&pps_idr, pps, id) | ||
391 | if (cookie == pps->lookup_cookie) | ||
392 | break; | ||
393 | rcu_read_unlock(); | ||
394 | return pps; | ||
395 | } | ||
396 | EXPORT_SYMBOL(pps_lookup_dev); | ||
397 | |||
398 | /* | ||
360 | * Module stuff | 399 | * Module stuff |
361 | */ | 400 | */ |
362 | 401 | ||
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig index 2c9a776bd63c..71bf959732fe 100644 --- a/drivers/s390/char/Kconfig +++ b/drivers/s390/char/Kconfig | |||
@@ -11,7 +11,7 @@ config TN3270 | |||
11 | config TN3270_TTY | 11 | config TN3270_TTY |
12 | def_tristate y | 12 | def_tristate y |
13 | prompt "Support for tty input/output on 3270 terminals" | 13 | prompt "Support for tty input/output on 3270 terminals" |
14 | depends on TN3270 | 14 | depends on TN3270 && TTY |
15 | help | 15 | help |
16 | Include support for using an IBM 3270 terminal as a Linux tty. | 16 | Include support for using an IBM 3270 terminal as a Linux tty. |
17 | 17 | ||
@@ -33,7 +33,7 @@ config TN3270_CONSOLE | |||
33 | config TN3215 | 33 | config TN3215 |
34 | def_bool y | 34 | def_bool y |
35 | prompt "Support for 3215 line mode terminal" | 35 | prompt "Support for 3215 line mode terminal" |
36 | depends on CCW | 36 | depends on CCW && TTY |
37 | help | 37 | help |
38 | Include support for IBM 3215 line-mode terminals. | 38 | Include support for IBM 3215 line-mode terminals. |
39 | 39 | ||
@@ -51,7 +51,7 @@ config CCW_CONSOLE | |||
51 | config SCLP_TTY | 51 | config SCLP_TTY |
52 | def_bool y | 52 | def_bool y |
53 | prompt "Support for SCLP line mode terminal" | 53 | prompt "Support for SCLP line mode terminal" |
54 | depends on S390 | 54 | depends on S390 && TTY |
55 | help | 55 | help |
56 | Include support for IBM SCLP line-mode terminals. | 56 | Include support for IBM SCLP line-mode terminals. |
57 | 57 | ||
@@ -66,7 +66,7 @@ config SCLP_CONSOLE | |||
66 | config SCLP_VT220_TTY | 66 | config SCLP_VT220_TTY |
67 | def_bool y | 67 | def_bool y |
68 | prompt "Support for SCLP VT220-compatible terminal" | 68 | prompt "Support for SCLP VT220-compatible terminal" |
69 | depends on S390 | 69 | depends on S390 && TTY |
70 | help | 70 | help |
71 | Include support for an IBM SCLP VT220-compatible terminal. | 71 | Include support for an IBM SCLP VT220-compatible terminal. |
72 | 72 | ||
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 33b7141a182f..7b00fa634d40 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -412,8 +412,9 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm, | |||
412 | break; | 412 | break; |
413 | 413 | ||
414 | case CTRLCHAR_CTRL: | 414 | case CTRLCHAR_CTRL: |
415 | tty_insert_flip_char(tty, cchar, TTY_NORMAL); | 415 | tty_insert_flip_char(&raw->port, cchar, |
416 | tty_flip_buffer_push(tty); | 416 | TTY_NORMAL); |
417 | tty_flip_buffer_push(&raw->port); | ||
417 | break; | 418 | break; |
418 | 419 | ||
419 | case CTRLCHAR_NONE: | 420 | case CTRLCHAR_NONE: |
@@ -425,8 +426,9 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm, | |||
425 | count++; | 426 | count++; |
426 | } else | 427 | } else |
427 | count -= 2; | 428 | count -= 2; |
428 | tty_insert_flip_string(tty, raw->inbuf, count); | 429 | tty_insert_flip_string(&raw->port, raw->inbuf, |
429 | tty_flip_buffer_push(tty); | 430 | count); |
431 | tty_flip_buffer_push(&raw->port); | ||
430 | break; | 432 | break; |
431 | } | 433 | } |
432 | } else if (req->type == RAW3215_WRITE) { | 434 | } else if (req->type == RAW3215_WRITE) { |
@@ -970,7 +972,7 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp) | |||
970 | 972 | ||
971 | tty_port_tty_set(&raw->port, tty); | 973 | tty_port_tty_set(&raw->port, tty); |
972 | 974 | ||
973 | tty->low_latency = 0; /* don't use bottom half for pushing chars */ | 975 | raw->port.low_latency = 0; /* don't use bottom half for pushing chars */ |
974 | /* | 976 | /* |
975 | * Start up 3215 device | 977 | * Start up 3215 device |
976 | */ | 978 | */ |
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h index d0ae2be58191..a31f339211d5 100644 --- a/drivers/s390/char/keyboard.h +++ b/drivers/s390/char/keyboard.h | |||
@@ -43,22 +43,14 @@ int kbd_ioctl(struct kbd_data *, unsigned int, unsigned long); | |||
43 | static inline void | 43 | static inline void |
44 | kbd_put_queue(struct tty_port *port, int ch) | 44 | kbd_put_queue(struct tty_port *port, int ch) |
45 | { | 45 | { |
46 | struct tty_struct *tty = tty_port_tty_get(port); | 46 | tty_insert_flip_char(port, ch, 0); |
47 | if (!tty) | 47 | tty_schedule_flip(port); |
48 | return; | ||
49 | tty_insert_flip_char(tty, ch, 0); | ||
50 | tty_schedule_flip(tty); | ||
51 | tty_kref_put(tty); | ||
52 | } | 48 | } |
53 | 49 | ||
54 | static inline void | 50 | static inline void |
55 | kbd_puts_queue(struct tty_port *port, char *cp) | 51 | kbd_puts_queue(struct tty_port *port, char *cp) |
56 | { | 52 | { |
57 | struct tty_struct *tty = tty_port_tty_get(port); | ||
58 | if (!tty) | ||
59 | return; | ||
60 | while (*cp) | 53 | while (*cp) |
61 | tty_insert_flip_char(tty, *cp++, 0); | 54 | tty_insert_flip_char(port, *cp++, 0); |
62 | tty_schedule_flip(tty); | 55 | tty_schedule_flip(port); |
63 | tty_kref_put(tty); | ||
64 | } | 56 | } |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 877fbc37c1e7..14b4cb8abcc8 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
@@ -65,7 +65,7 @@ sclp_tty_open(struct tty_struct *tty, struct file *filp) | |||
65 | { | 65 | { |
66 | tty_port_tty_set(&sclp_port, tty); | 66 | tty_port_tty_set(&sclp_port, tty); |
67 | tty->driver_data = NULL; | 67 | tty->driver_data = NULL; |
68 | tty->low_latency = 0; | 68 | sclp_port.low_latency = 0; |
69 | return 0; | 69 | return 0; |
70 | } | 70 | } |
71 | 71 | ||
@@ -342,8 +342,8 @@ sclp_tty_input(unsigned char* buf, unsigned int count) | |||
342 | case CTRLCHAR_SYSRQ: | 342 | case CTRLCHAR_SYSRQ: |
343 | break; | 343 | break; |
344 | case CTRLCHAR_CTRL: | 344 | case CTRLCHAR_CTRL: |
345 | tty_insert_flip_char(tty, cchar, TTY_NORMAL); | 345 | tty_insert_flip_char(&sclp_port, cchar, TTY_NORMAL); |
346 | tty_flip_buffer_push(tty); | 346 | tty_flip_buffer_push(&sclp_port); |
347 | break; | 347 | break; |
348 | case CTRLCHAR_NONE: | 348 | case CTRLCHAR_NONE: |
349 | /* send (normal) input to line discipline */ | 349 | /* send (normal) input to line discipline */ |
@@ -351,11 +351,11 @@ sclp_tty_input(unsigned char* buf, unsigned int count) | |||
351 | (strncmp((const char *) buf + count - 2, "^n", 2) && | 351 | (strncmp((const char *) buf + count - 2, "^n", 2) && |
352 | strncmp((const char *) buf + count - 2, "\252n", 2))) { | 352 | strncmp((const char *) buf + count - 2, "\252n", 2))) { |
353 | /* add the auto \n */ | 353 | /* add the auto \n */ |
354 | tty_insert_flip_string(tty, buf, count); | 354 | tty_insert_flip_string(&sclp_port, buf, count); |
355 | tty_insert_flip_char(tty, '\n', TTY_NORMAL); | 355 | tty_insert_flip_char(&sclp_port, '\n', TTY_NORMAL); |
356 | } else | 356 | } else |
357 | tty_insert_flip_string(tty, buf, count - 2); | 357 | tty_insert_flip_string(&sclp_port, buf, count - 2); |
358 | tty_flip_buffer_push(tty); | 358 | tty_flip_buffer_push(&sclp_port); |
359 | break; | 359 | break; |
360 | } | 360 | } |
361 | tty_kref_put(tty); | 361 | tty_kref_put(tty); |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index effcc8756e0a..6c92f62623be 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -461,14 +461,9 @@ sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
461 | static void | 461 | static void |
462 | sclp_vt220_receiver_fn(struct evbuf_header *evbuf) | 462 | sclp_vt220_receiver_fn(struct evbuf_header *evbuf) |
463 | { | 463 | { |
464 | struct tty_struct *tty = tty_port_tty_get(&sclp_vt220_port); | ||
465 | char *buffer; | 464 | char *buffer; |
466 | unsigned int count; | 465 | unsigned int count; |
467 | 466 | ||
468 | /* Ignore input if device is not open */ | ||
469 | if (tty == NULL) | ||
470 | return; | ||
471 | |||
472 | buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header)); | 467 | buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header)); |
473 | count = evbuf->length - sizeof(struct evbuf_header); | 468 | count = evbuf->length - sizeof(struct evbuf_header); |
474 | 469 | ||
@@ -480,11 +475,10 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf) | |||
480 | /* Send input to line discipline */ | 475 | /* Send input to line discipline */ |
481 | buffer++; | 476 | buffer++; |
482 | count--; | 477 | count--; |
483 | tty_insert_flip_string(tty, buffer, count); | 478 | tty_insert_flip_string(&sclp_vt220_port, buffer, count); |
484 | tty_flip_buffer_push(tty); | 479 | tty_flip_buffer_push(&sclp_vt220_port); |
485 | break; | 480 | break; |
486 | } | 481 | } |
487 | tty_kref_put(tty); | ||
488 | } | 482 | } |
489 | 483 | ||
490 | /* | 484 | /* |
@@ -495,7 +489,7 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp) | |||
495 | { | 489 | { |
496 | if (tty->count == 1) { | 490 | if (tty->count == 1) { |
497 | tty_port_tty_set(&sclp_vt220_port, tty); | 491 | tty_port_tty_set(&sclp_vt220_port, tty); |
498 | tty->low_latency = 0; | 492 | sclp_vt220_port.low_latency = 0; |
499 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | 493 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { |
500 | tty->winsize.ws_row = 24; | 494 | tty->winsize.ws_row = 24; |
501 | tty->winsize.ws_col = 80; | 495 | tty->winsize.ws_col = 80; |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 43ea0593bdb0..3860e796b65f 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
@@ -860,7 +860,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) | |||
860 | tty->driver_data = tp; | 860 | tty->driver_data = tp; |
861 | tty->winsize.ws_row = tp->view.rows - 2; | 861 | tty->winsize.ws_row = tp->view.rows - 2; |
862 | tty->winsize.ws_col = tp->view.cols; | 862 | tty->winsize.ws_col = tp->view.cols; |
863 | tty->low_latency = 0; | 863 | tp->port.low_latency = 0; |
864 | /* why to reassign? */ | 864 | /* why to reassign? */ |
865 | tty_port_tty_set(&tp->port, tty); | 865 | tty_port_tty_set(&tp->port, tty); |
866 | tp->inattr = TF_INPUT; | 866 | tp->inattr = TF_INPUT; |
@@ -893,7 +893,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) | |||
893 | } | 893 | } |
894 | 894 | ||
895 | tty_port_tty_set(&tp->port, tty); | 895 | tty_port_tty_set(&tp->port, tty); |
896 | tty->low_latency = 0; | 896 | tp->port.low_latency = 0; |
897 | tty->winsize.ws_row = tp->view.rows - 2; | 897 | tty->winsize.ws_row = tp->view.rows - 2; |
898 | tty->winsize.ws_col = tp->view.cols; | 898 | tty->winsize.ws_col = tp->view.cols; |
899 | 899 | ||
diff --git a/drivers/staging/ccg/Kconfig b/drivers/staging/ccg/Kconfig index 8997a8c757aa..7ed5bc6caadb 100644 --- a/drivers/staging/ccg/Kconfig +++ b/drivers/staging/ccg/Kconfig | |||
@@ -2,7 +2,7 @@ if USB_GADGET | |||
2 | 2 | ||
3 | config USB_G_CCG | 3 | config USB_G_CCG |
4 | tristate "Configurable Composite Gadget (STAGING)" | 4 | tristate "Configurable Composite Gadget (STAGING)" |
5 | depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM | 5 | depends on STAGING && BLOCK && NET && !USB_ZERO && !USB_ZERO_HNPTEST && !USB_AUDIO && !GADGET_UAC1 && !USB_ETH && !USB_ETH_RNDIS && !USB_ETH_EEM && !USB_G_NCM && !USB_GADGETFS && !USB_FUNCTIONFS && !USB_FUNCTIONFS_ETH && !USB_FUNCTIONFS_RNDIS && !USB_FUNCTIONFS_GENERIC && !USB_FILE_STORAGE && !USB_FILE_STORAGE_TEST && !USB_MASS_STORAGE && !USB_G_SERIAL && !USB_MIDI_GADGET && !USB_G_PRINTER && !USB_CDC_COMPOSITE && !USB_G_NOKIA && !USB_G_ACM_MS && !USB_G_MULTI && !USB_G_MULTI_RNDIS && !USB_G_MULTI_CDC && !USB_G_HID && !USB_G_DBGP && !USB_G_WEBCAM && TTY |
6 | help | 6 | help |
7 | The Configurable Composite Gadget supports multiple USB | 7 | The Configurable Composite Gadget supports multiple USB |
8 | functions: acm, mass storage, rndis and FunctionFS. | 8 | functions: acm, mass storage, rndis and FunctionFS. |
diff --git a/drivers/staging/ccg/u_serial.c b/drivers/staging/ccg/u_serial.c index 373c40656b52..b10947ae0ac5 100644 --- a/drivers/staging/ccg/u_serial.c +++ b/drivers/staging/ccg/u_serial.c | |||
@@ -491,12 +491,8 @@ static void gs_rx_push(unsigned long _port) | |||
491 | 491 | ||
492 | req = list_first_entry(queue, struct usb_request, list); | 492 | req = list_first_entry(queue, struct usb_request, list); |
493 | 493 | ||
494 | /* discard data if tty was closed */ | ||
495 | if (!tty) | ||
496 | goto recycle; | ||
497 | |||
498 | /* leave data queued if tty was rx throttled */ | 494 | /* leave data queued if tty was rx throttled */ |
499 | if (test_bit(TTY_THROTTLED, &tty->flags)) | 495 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) |
500 | break; | 496 | break; |
501 | 497 | ||
502 | switch (req->status) { | 498 | switch (req->status) { |
@@ -529,7 +525,7 @@ static void gs_rx_push(unsigned long _port) | |||
529 | size -= n; | 525 | size -= n; |
530 | } | 526 | } |
531 | 527 | ||
532 | count = tty_insert_flip_string(tty, packet, size); | 528 | count = tty_insert_flip_string(&port->port, packet, size); |
533 | if (count) | 529 | if (count) |
534 | do_push = true; | 530 | do_push = true; |
535 | if (count != size) { | 531 | if (count != size) { |
@@ -542,7 +538,6 @@ static void gs_rx_push(unsigned long _port) | |||
542 | } | 538 | } |
543 | port->n_read = 0; | 539 | port->n_read = 0; |
544 | } | 540 | } |
545 | recycle: | ||
546 | list_move(&req->list, &port->read_pool); | 541 | list_move(&req->list, &port->read_pool); |
547 | port->read_started--; | 542 | port->read_started--; |
548 | } | 543 | } |
@@ -550,8 +545,8 @@ recycle: | |||
550 | /* Push from tty to ldisc; without low_latency set this is handled by | 545 | /* Push from tty to ldisc; without low_latency set this is handled by |
551 | * a workqueue, so we won't get callbacks and can hold port_lock | 546 | * a workqueue, so we won't get callbacks and can hold port_lock |
552 | */ | 547 | */ |
553 | if (tty && do_push) | 548 | if (do_push) |
554 | tty_flip_buffer_push(tty); | 549 | tty_flip_buffer_push(&port->port); |
555 | 550 | ||
556 | 551 | ||
557 | /* We want our data queue to become empty ASAP, keeping data | 552 | /* We want our data queue to become empty ASAP, keeping data |
diff --git a/drivers/staging/dgrp/Kconfig b/drivers/staging/dgrp/Kconfig index 39f4bb65ec83..e4c41552923a 100644 --- a/drivers/staging/dgrp/Kconfig +++ b/drivers/staging/dgrp/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | config DGRP | 1 | config DGRP |
2 | tristate "Digi Realport driver" | 2 | tristate "Digi Realport driver" |
3 | default n | 3 | default n |
4 | depends on SYSFS | 4 | depends on SYSFS && TTY |
5 | ---help--- | 5 | ---help--- |
6 | Support for Digi Realport devices. These devices allow you to | 6 | Support for Digi Realport devices. These devices allow you to |
7 | access remote serial ports as if they are local tty devices. This | 7 | access remote serial ports as if they are local tty devices. This |
diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 2d1bbfd5b67c..e6018823b9de 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/types.h> | 38 | #include <linux/types.h> |
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/device.h> | ||
40 | #include <linux/tty.h> | 41 | #include <linux/tty.h> |
41 | #include <linux/tty_flip.h> | 42 | #include <linux/tty_flip.h> |
42 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
@@ -211,7 +212,7 @@ static void dgrp_input(struct ch_struct *ch) | |||
211 | data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; | 212 | data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; |
212 | 213 | ||
213 | /* len is the amount of data we are going to transfer here */ | 214 | /* len is the amount of data we are going to transfer here */ |
214 | len = tty_buffer_request_room(tty, data_len); | 215 | len = tty_buffer_request_room(&ch->port, data_len); |
215 | 216 | ||
216 | /* Check DPA flow control */ | 217 | /* Check DPA flow control */ |
217 | if ((nd->nd_dpa_debug) && | 218 | if ((nd->nd_dpa_debug) && |
@@ -232,9 +233,9 @@ static void dgrp_input(struct ch_struct *ch) | |||
232 | (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) | 233 | (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) |
233 | dgrp_dpa_data(nd, 1, myflipbuf, len); | 234 | dgrp_dpa_data(nd, 1, myflipbuf, len); |
234 | 235 | ||
235 | tty_insert_flip_string_flags(tty, myflipbuf, | 236 | tty_insert_flip_string_flags(&ch->port, myflipbuf, |
236 | myflipflagbuf, len); | 237 | myflipflagbuf, len); |
237 | tty_flip_buffer_push(tty); | 238 | tty_flip_buffer_push(&ch->port); |
238 | 239 | ||
239 | ch->ch_rxcount += len; | 240 | ch->ch_rxcount += len; |
240 | } | 241 | } |
@@ -2956,9 +2957,9 @@ check_query: | |||
2956 | I_BRKINT(ch->ch_tun.un_tty) && | 2957 | I_BRKINT(ch->ch_tun.un_tty) && |
2957 | !(I_IGNBRK(ch->ch_tun.un_tty))) { | 2958 | !(I_IGNBRK(ch->ch_tun.un_tty))) { |
2958 | 2959 | ||
2959 | tty_buffer_request_room(ch->ch_tun.un_tty, 1); | 2960 | tty_buffer_request_room(&ch->port, 1); |
2960 | tty_insert_flip_char(ch->ch_tun.un_tty, 0, TTY_BREAK); | 2961 | tty_insert_flip_char(&ch->port, 0, TTY_BREAK); |
2961 | tty_flip_buffer_push(ch->ch_tun.un_tty); | 2962 | tty_flip_buffer_push(&ch->port); |
2962 | 2963 | ||
2963 | } | 2964 | } |
2964 | 2965 | ||
diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index 51d3ed3dca27..654f6010b473 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/tty.h> | 40 | #include <linux/tty.h> |
41 | #include <linux/tty_flip.h> | 41 | #include <linux/tty_flip.h> |
42 | #include <linux/device.h> | ||
42 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
43 | #include <linux/uaccess.h> | 44 | #include <linux/uaccess.h> |
44 | 45 | ||
diff --git a/drivers/staging/fwserial/Kconfig b/drivers/staging/fwserial/Kconfig index b2f8331e4acf..a0812d99136f 100644 --- a/drivers/staging/fwserial/Kconfig +++ b/drivers/staging/fwserial/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config FIREWIRE_SERIAL | 1 | config FIREWIRE_SERIAL |
2 | tristate "TTY over Firewire" | 2 | tristate "TTY over Firewire" |
3 | depends on FIREWIRE | 3 | depends on FIREWIRE && TTY |
4 | help | 4 | help |
5 | This enables TTY over IEEE 1394, providing high-speed serial | 5 | This enables TTY over IEEE 1394, providing high-speed serial |
6 | connectivity to cabled peers. This driver implements a | 6 | connectivity to cabled peers. This driver implements a |
diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 8859c75f16fa..5a6fb44f38a8 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c | |||
@@ -500,16 +500,11 @@ static void fwtty_do_hangup(struct work_struct *work) | |||
500 | static void fwtty_emit_breaks(struct work_struct *work) | 500 | static void fwtty_emit_breaks(struct work_struct *work) |
501 | { | 501 | { |
502 | struct fwtty_port *port = to_port(to_delayed_work(work), emit_breaks); | 502 | struct fwtty_port *port = to_port(to_delayed_work(work), emit_breaks); |
503 | struct tty_struct *tty; | ||
504 | static const char buf[16]; | 503 | static const char buf[16]; |
505 | unsigned long now = jiffies; | 504 | unsigned long now = jiffies; |
506 | unsigned long elapsed = now - port->break_last; | 505 | unsigned long elapsed = now - port->break_last; |
507 | int n, t, c, brk = 0; | 506 | int n, t, c, brk = 0; |
508 | 507 | ||
509 | tty = tty_port_tty_get(&port->port); | ||
510 | if (!tty) | ||
511 | return; | ||
512 | |||
513 | /* generate breaks at the line rate (but at least 1) */ | 508 | /* generate breaks at the line rate (but at least 1) */ |
514 | n = (elapsed * port->cps) / HZ + 1; | 509 | n = (elapsed * port->cps) / HZ + 1; |
515 | port->break_last = now; | 510 | port->break_last = now; |
@@ -518,15 +513,14 @@ static void fwtty_emit_breaks(struct work_struct *work) | |||
518 | 513 | ||
519 | while (n) { | 514 | while (n) { |
520 | t = min(n, 16); | 515 | t = min(n, 16); |
521 | c = tty_insert_flip_string_fixed_flag(tty, buf, TTY_BREAK, t); | 516 | c = tty_insert_flip_string_fixed_flag(&port->port, buf, |
517 | TTY_BREAK, t); | ||
522 | n -= c; | 518 | n -= c; |
523 | brk += c; | 519 | brk += c; |
524 | if (c < t) | 520 | if (c < t) |
525 | break; | 521 | break; |
526 | } | 522 | } |
527 | tty_flip_buffer_push(tty); | 523 | tty_flip_buffer_push(&port->port); |
528 | |||
529 | tty_kref_put(tty); | ||
530 | 524 | ||
531 | if (port->mstatus & (UART_LSR_BI << 24)) | 525 | if (port->mstatus & (UART_LSR_BI << 24)) |
532 | schedule_delayed_work(&port->emit_breaks, FREQ_BREAKS); | 526 | schedule_delayed_work(&port->emit_breaks, FREQ_BREAKS); |
@@ -540,13 +534,9 @@ static void fwtty_pushrx(struct work_struct *work) | |||
540 | struct buffered_rx *buf, *next; | 534 | struct buffered_rx *buf, *next; |
541 | int n, c = 0; | 535 | int n, c = 0; |
542 | 536 | ||
543 | tty = tty_port_tty_get(&port->port); | ||
544 | if (!tty) | ||
545 | return; | ||
546 | |||
547 | spin_lock_bh(&port->lock); | 537 | spin_lock_bh(&port->lock); |
548 | list_for_each_entry_safe(buf, next, &port->buf_list, list) { | 538 | list_for_each_entry_safe(buf, next, &port->buf_list, list) { |
549 | n = tty_insert_flip_string_fixed_flag(tty, buf->data, | 539 | n = tty_insert_flip_string_fixed_flag(&port->port, buf->data, |
550 | TTY_NORMAL, buf->n); | 540 | TTY_NORMAL, buf->n); |
551 | c += n; | 541 | c += n; |
552 | port->buffered -= n; | 542 | port->buffered -= n; |
@@ -555,7 +545,11 @@ static void fwtty_pushrx(struct work_struct *work) | |||
555 | memmove(buf->data, buf->data + n, buf->n - n); | 545 | memmove(buf->data, buf->data + n, buf->n - n); |
556 | buf->n -= n; | 546 | buf->n -= n; |
557 | } | 547 | } |
558 | __fwtty_throttle(port, tty); | 548 | tty = tty_port_tty_get(&port->port); |
549 | if (tty) { | ||
550 | __fwtty_throttle(port, tty); | ||
551 | tty_kref_put(tty); | ||
552 | } | ||
559 | break; | 553 | break; |
560 | } else { | 554 | } else { |
561 | list_del(&buf->list); | 555 | list_del(&buf->list); |
@@ -563,13 +557,11 @@ static void fwtty_pushrx(struct work_struct *work) | |||
563 | } | 557 | } |
564 | } | 558 | } |
565 | if (c > 0) | 559 | if (c > 0) |
566 | tty_flip_buffer_push(tty); | 560 | tty_flip_buffer_push(&port->port); |
567 | 561 | ||
568 | if (list_empty(&port->buf_list)) | 562 | if (list_empty(&port->buf_list)) |
569 | clear_bit(BUFFERING_RX, &port->flags); | 563 | clear_bit(BUFFERING_RX, &port->flags); |
570 | spin_unlock_bh(&port->lock); | 564 | spin_unlock_bh(&port->lock); |
571 | |||
572 | tty_kref_put(tty); | ||
573 | } | 565 | } |
574 | 566 | ||
575 | static int fwtty_buffer_rx(struct fwtty_port *port, unsigned char *d, size_t n) | 567 | static int fwtty_buffer_rx(struct fwtty_port *port, unsigned char *d, size_t n) |
@@ -607,10 +599,6 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) | |||
607 | unsigned lsr; | 599 | unsigned lsr; |
608 | int err = 0; | 600 | int err = 0; |
609 | 601 | ||
610 | tty = tty_port_tty_get(&port->port); | ||
611 | if (!tty) | ||
612 | return -ENOENT; | ||
613 | |||
614 | fwtty_dbg(port, "%d", n); | 602 | fwtty_dbg(port, "%d", n); |
615 | profile_size_distrib(port->stats.reads, n); | 603 | profile_size_distrib(port->stats.reads, n); |
616 | 604 | ||
@@ -630,7 +618,7 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) | |||
630 | 618 | ||
631 | lsr &= port->status_mask; | 619 | lsr &= port->status_mask; |
632 | if (lsr & ~port->ignore_mask & UART_LSR_OE) { | 620 | if (lsr & ~port->ignore_mask & UART_LSR_OE) { |
633 | if (!tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { | 621 | if (!tty_insert_flip_char(&port->port, 0, TTY_OVERRUN)) { |
634 | err = -EIO; | 622 | err = -EIO; |
635 | goto out; | 623 | goto out; |
636 | } | 624 | } |
@@ -644,18 +632,23 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) | |||
644 | } | 632 | } |
645 | 633 | ||
646 | if (!test_bit(BUFFERING_RX, &port->flags)) { | 634 | if (!test_bit(BUFFERING_RX, &port->flags)) { |
647 | c = tty_insert_flip_string_fixed_flag(tty, data, TTY_NORMAL, n); | 635 | c = tty_insert_flip_string_fixed_flag(&port->port, data, |
636 | TTY_NORMAL, n); | ||
648 | if (c > 0) | 637 | if (c > 0) |
649 | tty_flip_buffer_push(tty); | 638 | tty_flip_buffer_push(&port->port); |
650 | n -= c; | 639 | n -= c; |
651 | 640 | ||
652 | if (n) { | 641 | if (n) { |
653 | /* start buffering and throttling */ | 642 | /* start buffering and throttling */ |
654 | n -= fwtty_buffer_rx(port, &data[c], n); | 643 | n -= fwtty_buffer_rx(port, &data[c], n); |
655 | 644 | ||
656 | spin_lock_bh(&port->lock); | 645 | tty = tty_port_tty_get(&port->port); |
657 | __fwtty_throttle(port, tty); | 646 | if (tty) { |
658 | spin_unlock_bh(&port->lock); | 647 | spin_lock_bh(&port->lock); |
648 | __fwtty_throttle(port, tty); | ||
649 | spin_unlock_bh(&port->lock); | ||
650 | tty_kref_put(tty); | ||
651 | } | ||
659 | } | 652 | } |
660 | } else | 653 | } else |
661 | n -= fwtty_buffer_rx(port, data, n); | 654 | n -= fwtty_buffer_rx(port, data, n); |
@@ -666,8 +659,6 @@ static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) | |||
666 | } | 659 | } |
667 | 660 | ||
668 | out: | 661 | out: |
669 | tty_kref_put(tty); | ||
670 | |||
671 | port->icount.rx += len; | 662 | port->icount.rx += len; |
672 | port->stats.lost += n; | 663 | port->stats.lost += n; |
673 | return err; | 664 | return err; |
diff --git a/drivers/staging/sb105x/Kconfig b/drivers/staging/sb105x/Kconfig index 1facad625554..245e7847a354 100644 --- a/drivers/staging/sb105x/Kconfig +++ b/drivers/staging/sb105x/Kconfig | |||
@@ -1,8 +1,7 @@ | |||
1 | config SB105X | 1 | config SB105X |
2 | tristate "SystemBase PCI Multiport UART" | 2 | tristate "SystemBase PCI Multiport UART" |
3 | select SERIAL_CORE | 3 | select SERIAL_CORE |
4 | depends on PCI | 4 | depends on PCI && X86 && TTY && BROKEN |
5 | depends on X86 | ||
6 | help | 5 | help |
7 | A driver for the SystemBase Multi-2/PCI serial card | 6 | A driver for the SystemBase Multi-2/PCI serial card |
8 | 7 | ||
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 1b3e995d3a27..b1bb1a6abe81 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c | |||
@@ -255,12 +255,11 @@ static void ProcessModemStatus(struct quatech_port *qt_port, | |||
255 | wake_up_interruptible(&qt_port->wait); | 255 | wake_up_interruptible(&qt_port->wait); |
256 | } | 256 | } |
257 | 257 | ||
258 | static void ProcessRxChar(struct tty_struct *tty, struct usb_serial_port *port, | 258 | static void ProcessRxChar(struct usb_serial_port *port, unsigned char data) |
259 | unsigned char data) | ||
260 | { | 259 | { |
261 | struct urb *urb = port->read_urb; | 260 | struct urb *urb = port->read_urb; |
262 | if (urb->actual_length) | 261 | if (urb->actual_length) |
263 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 262 | tty_insert_flip_char(&port->port, data, TTY_NORMAL); |
264 | } | 263 | } |
265 | 264 | ||
266 | static void qt_write_bulk_callback(struct urb *urb) | 265 | static void qt_write_bulk_callback(struct urb *urb) |
@@ -291,8 +290,7 @@ static void qt_interrupt_callback(struct urb *urb) | |||
291 | /* FIXME */ | 290 | /* FIXME */ |
292 | } | 291 | } |
293 | 292 | ||
294 | static void qt_status_change_check(struct tty_struct *tty, | 293 | static void qt_status_change_check(struct urb *urb, |
295 | struct urb *urb, | ||
296 | struct quatech_port *qt_port, | 294 | struct quatech_port *qt_port, |
297 | struct usb_serial_port *port) | 295 | struct usb_serial_port *port) |
298 | { | 296 | { |
@@ -335,8 +333,8 @@ static void qt_status_change_check(struct tty_struct *tty, | |||
335 | case 0xff: | 333 | case 0xff: |
336 | dev_dbg(&port->dev, "No status sequence.\n"); | 334 | dev_dbg(&port->dev, "No status sequence.\n"); |
337 | 335 | ||
338 | ProcessRxChar(tty, port, data[i]); | 336 | ProcessRxChar(port, data[i]); |
339 | ProcessRxChar(tty, port, data[i + 1]); | 337 | ProcessRxChar(port, data[i + 1]); |
340 | 338 | ||
341 | i += 2; | 339 | i += 2; |
342 | break; | 340 | break; |
@@ -345,11 +343,11 @@ static void qt_status_change_check(struct tty_struct *tty, | |||
345 | continue; | 343 | continue; |
346 | } | 344 | } |
347 | 345 | ||
348 | if (tty && urb->actual_length) | 346 | if (urb->actual_length) |
349 | tty_insert_flip_char(tty, data[i], TTY_NORMAL); | 347 | tty_insert_flip_char(&port->port, data[i], TTY_NORMAL); |
350 | 348 | ||
351 | } | 349 | } |
352 | tty_flip_buffer_push(tty); | 350 | tty_flip_buffer_push(&port->port); |
353 | } | 351 | } |
354 | 352 | ||
355 | static void qt_read_bulk_callback(struct urb *urb) | 353 | static void qt_read_bulk_callback(struct urb *urb) |
@@ -358,7 +356,6 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
358 | struct usb_serial_port *port = urb->context; | 356 | struct usb_serial_port *port = urb->context; |
359 | struct usb_serial *serial = get_usb_serial(port, __func__); | 357 | struct usb_serial *serial = get_usb_serial(port, __func__); |
360 | struct quatech_port *qt_port = qt_get_port_private(port); | 358 | struct quatech_port *qt_port = qt_get_port_private(port); |
361 | struct tty_struct *tty; | ||
362 | int result; | 359 | int result; |
363 | 360 | ||
364 | if (urb->status) { | 361 | if (urb->status) { |
@@ -369,27 +366,23 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
369 | return; | 366 | return; |
370 | } | 367 | } |
371 | 368 | ||
372 | tty = tty_port_tty_get(&port->port); | ||
373 | if (!tty) | ||
374 | return; | ||
375 | |||
376 | dev_dbg(&port->dev, | 369 | dev_dbg(&port->dev, |
377 | "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); | 370 | "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); |
378 | 371 | ||
379 | if (port_paranoia_check(port, __func__) != 0) { | 372 | if (port_paranoia_check(port, __func__) != 0) { |
380 | qt_port->ReadBulkStopped = 1; | 373 | qt_port->ReadBulkStopped = 1; |
381 | goto exit; | 374 | return; |
382 | } | 375 | } |
383 | 376 | ||
384 | if (!serial) | 377 | if (!serial) |
385 | goto exit; | 378 | return; |
386 | 379 | ||
387 | if (qt_port->closePending == 1) { | 380 | if (qt_port->closePending == 1) { |
388 | /* Were closing , stop reading */ | 381 | /* Were closing , stop reading */ |
389 | dev_dbg(&port->dev, | 382 | dev_dbg(&port->dev, |
390 | "%s - (qt_port->closepending == 1\n", __func__); | 383 | "%s - (qt_port->closepending == 1\n", __func__); |
391 | qt_port->ReadBulkStopped = 1; | 384 | qt_port->ReadBulkStopped = 1; |
392 | goto exit; | 385 | return; |
393 | } | 386 | } |
394 | 387 | ||
395 | /* | 388 | /* |
@@ -399,7 +392,7 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
399 | */ | 392 | */ |
400 | if (qt_port->RxHolding == 1) { | 393 | if (qt_port->RxHolding == 1) { |
401 | qt_port->ReadBulkStopped = 1; | 394 | qt_port->ReadBulkStopped = 1; |
402 | goto exit; | 395 | return; |
403 | } | 396 | } |
404 | 397 | ||
405 | if (urb->status) { | 398 | if (urb->status) { |
@@ -408,11 +401,11 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
408 | dev_dbg(&port->dev, | 401 | dev_dbg(&port->dev, |
409 | "%s - nonzero read bulk status received: %d\n", | 402 | "%s - nonzero read bulk status received: %d\n", |
410 | __func__, urb->status); | 403 | __func__, urb->status); |
411 | goto exit; | 404 | return; |
412 | } | 405 | } |
413 | 406 | ||
414 | if (urb->actual_length) | 407 | if (urb->actual_length) |
415 | qt_status_change_check(tty, urb, qt_port, port); | 408 | qt_status_change_check(urb, qt_port, port); |
416 | 409 | ||
417 | /* Continue trying to always read */ | 410 | /* Continue trying to always read */ |
418 | usb_fill_bulk_urb(port->read_urb, serial->dev, | 411 | usb_fill_bulk_urb(port->read_urb, serial->dev, |
@@ -428,14 +421,12 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
428 | __func__, result); | 421 | __func__, result); |
429 | else { | 422 | else { |
430 | if (urb->actual_length) { | 423 | if (urb->actual_length) { |
431 | tty_flip_buffer_push(tty); | 424 | tty_flip_buffer_push(&port->port); |
432 | tty_schedule_flip(tty); | 425 | tty_schedule_flip(&port->port); |
433 | } | 426 | } |
434 | } | 427 | } |
435 | 428 | ||
436 | schedule_work(&port->work); | 429 | schedule_work(&port->work); |
437 | exit: | ||
438 | tty_kref_put(tty); | ||
439 | } | 430 | } |
440 | 431 | ||
441 | /* | 432 | /* |
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index 822ac3d24788..775af26b9914 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/consolemap.h> | 2 | #include <linux/consolemap.h> |
3 | #include <linux/interrupt.h> | 3 | #include <linux/interrupt.h> |
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | #include <linux/device.h> /* for dev_warn */ | ||
5 | #include <linux/selection.h> | 6 | #include <linux/selection.h> |
6 | 7 | ||
7 | #include "speakup.h" | 8 | #include "speakup.h" |
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 0ecf22b6a38e..978db344bda0 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig | |||
@@ -1,3 +1,14 @@ | |||
1 | config TTY | ||
2 | bool "Enable TTY" if EXPERT | ||
3 | default y | ||
4 | ---help--- | ||
5 | Allows you to remove TTY support which can save space, and | ||
6 | blocks features that require TTY from inclusion in the kernel. | ||
7 | TTY is required for any text terminals or serial port | ||
8 | communication. Most users should leave this enabled. | ||
9 | |||
10 | if TTY | ||
11 | |||
1 | config VT | 12 | config VT |
2 | bool "Virtual terminal" if EXPERT | 13 | bool "Virtual terminal" if EXPERT |
3 | depends on !S390 && !UML | 14 | depends on !S390 && !UML |
@@ -388,3 +399,24 @@ config PPC_EARLY_DEBUG_EHV_BC_HANDLE | |||
388 | If the number you specify is not a valid byte channel handle, then | 399 | If the number you specify is not a valid byte channel handle, then |
389 | there simply will be no early console output. This is true also | 400 | there simply will be no early console output. This is true also |
390 | if you don't boot under a hypervisor at all. | 401 | if you don't boot under a hypervisor at all. |
402 | |||
403 | config GOLDFISH_TTY | ||
404 | tristate "Goldfish TTY Driver" | ||
405 | depends on GOLDFISH | ||
406 | help | ||
407 | Console and system TTY driver for the Goldfish virtual platform. | ||
408 | |||
409 | config DA_TTY | ||
410 | bool "DA TTY" | ||
411 | depends on METAG_DA | ||
412 | select SERIAL_NONSTANDARD | ||
413 | help | ||
414 | This enables a TTY on a Dash channel. | ||
415 | |||
416 | config DA_CONSOLE | ||
417 | bool "DA Console" | ||
418 | depends on DA_TTY | ||
419 | help | ||
420 | This enables a console on a Dash channel. | ||
421 | |||
422 | endif # TTY | ||
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 2953059530e4..6b78399bc7c9 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ | 1 | obj-$(CONFIG_TTY) += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ |
2 | tty_buffer.o tty_port.o tty_mutex.o | 2 | tty_buffer.o tty_port.o tty_mutex.o |
3 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | 3 | obj-$(CONFIG_LEGACY_PTYS) += pty.o |
4 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | 4 | obj-$(CONFIG_UNIX98_PTYS) += pty.o |
@@ -27,5 +27,7 @@ obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o | |||
27 | obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o | 27 | obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o |
28 | obj-$(CONFIG_SYNCLINK) += synclink.o | 28 | obj-$(CONFIG_SYNCLINK) += synclink.o |
29 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o | 29 | obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o |
30 | obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o | ||
31 | obj-$(CONFIG_DA_TTY) += metag_da.o | ||
30 | 32 | ||
31 | obj-y += ipwireless/ | 33 | obj-y += ipwireless/ |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 9d7d00cdfecb..fc700342d43f 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -251,7 +251,6 @@ static void receive_chars(struct serial_state *info) | |||
251 | { | 251 | { |
252 | int status; | 252 | int status; |
253 | int serdatr; | 253 | int serdatr; |
254 | struct tty_struct *tty = info->tport.tty; | ||
255 | unsigned char ch, flag; | 254 | unsigned char ch, flag; |
256 | struct async_icount *icount; | 255 | struct async_icount *icount; |
257 | int oe = 0; | 256 | int oe = 0; |
@@ -314,7 +313,7 @@ static void receive_chars(struct serial_state *info) | |||
314 | #endif | 313 | #endif |
315 | flag = TTY_BREAK; | 314 | flag = TTY_BREAK; |
316 | if (info->tport.flags & ASYNC_SAK) | 315 | if (info->tport.flags & ASYNC_SAK) |
317 | do_SAK(tty); | 316 | do_SAK(info->tport.tty); |
318 | } else if (status & UART_LSR_PE) | 317 | } else if (status & UART_LSR_PE) |
319 | flag = TTY_PARITY; | 318 | flag = TTY_PARITY; |
320 | else if (status & UART_LSR_FE) | 319 | else if (status & UART_LSR_FE) |
@@ -328,10 +327,10 @@ static void receive_chars(struct serial_state *info) | |||
328 | oe = 1; | 327 | oe = 1; |
329 | } | 328 | } |
330 | } | 329 | } |
331 | tty_insert_flip_char(tty, ch, flag); | 330 | tty_insert_flip_char(&info->tport, ch, flag); |
332 | if (oe == 1) | 331 | if (oe == 1) |
333 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 332 | tty_insert_flip_char(&info->tport, 0, TTY_OVERRUN); |
334 | tty_flip_buffer_push(tty); | 333 | tty_flip_buffer_push(&info->tport); |
335 | out: | 334 | out: |
336 | return; | 335 | return; |
337 | } | 336 | } |
@@ -394,11 +393,6 @@ static void check_modem_status(struct serial_state *info) | |||
394 | icount->dsr++; | 393 | icount->dsr++; |
395 | if (dstatus & SER_DCD) { | 394 | if (dstatus & SER_DCD) { |
396 | icount->dcd++; | 395 | icount->dcd++; |
397 | #ifdef CONFIG_HARD_PPS | ||
398 | if ((port->flags & ASYNC_HARDPPS_CD) && | ||
399 | !(status & SER_DCD)) | ||
400 | hardpps(); | ||
401 | #endif | ||
402 | } | 396 | } |
403 | if (dstatus & SER_CTS) | 397 | if (dstatus & SER_CTS) |
404 | icount->cts++; | 398 | icount->cts++; |
@@ -1099,7 +1093,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
1099 | state->custom_divisor = new_serial.custom_divisor; | 1093 | state->custom_divisor = new_serial.custom_divisor; |
1100 | port->close_delay = new_serial.close_delay * HZ/100; | 1094 | port->close_delay = new_serial.close_delay * HZ/100; |
1101 | port->closing_wait = new_serial.closing_wait * HZ/100; | 1095 | port->closing_wait = new_serial.closing_wait * HZ/100; |
1102 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1096 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1103 | 1097 | ||
1104 | check_and_exit: | 1098 | check_and_exit: |
1105 | if (port->flags & ASYNC_INITIALIZED) { | 1099 | if (port->flags & ASYNC_INITIALIZED) { |
@@ -1528,7 +1522,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp) | |||
1528 | if (serial_paranoia_check(info, tty->name, "rs_open")) | 1522 | if (serial_paranoia_check(info, tty->name, "rs_open")) |
1529 | return -ENODEV; | 1523 | return -ENODEV; |
1530 | 1524 | ||
1531 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1525 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1532 | 1526 | ||
1533 | retval = startup(tty, info); | 1527 | retval = startup(tty, info); |
1534 | if (retval) { | 1528 | if (retval) { |
diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c index 1cfcdbf1d0cc..a93a424873fa 100644 --- a/drivers/tty/bfin_jtag_comm.c +++ b/drivers/tty/bfin_jtag_comm.c | |||
@@ -95,18 +95,16 @@ bfin_jc_emudat_manager(void *arg) | |||
95 | 95 | ||
96 | /* if incoming data is ready, eat it */ | 96 | /* if incoming data is ready, eat it */ |
97 | if (bfin_read_DBGSTAT() & EMUDIF) { | 97 | if (bfin_read_DBGSTAT() & EMUDIF) { |
98 | if (tty != NULL) { | 98 | uint32_t emudat = bfin_read_emudat(); |
99 | uint32_t emudat = bfin_read_emudat(); | 99 | if (inbound_len == 0) { |
100 | if (inbound_len == 0) { | 100 | pr_debug("incoming length: 0x%08x\n", emudat); |
101 | pr_debug("incoming length: 0x%08x\n", emudat); | 101 | inbound_len = emudat; |
102 | inbound_len = emudat; | 102 | } else { |
103 | } else { | 103 | size_t num_chars = (4 <= inbound_len ? 4 : inbound_len); |
104 | size_t num_chars = (4 <= inbound_len ? 4 : inbound_len); | 104 | pr_debug(" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars); |
105 | pr_debug(" incoming data: 0x%08x (pushing %zu)\n", emudat, num_chars); | 105 | inbound_len -= num_chars; |
106 | inbound_len -= num_chars; | 106 | tty_insert_flip_string(&port, (unsigned char *)&emudat, num_chars); |
107 | tty_insert_flip_string(tty, (unsigned char *)&emudat, num_chars); | 107 | tty_flip_buffer_push(&port); |
108 | tty_flip_buffer_push(tty); | ||
109 | } | ||
110 | } | 108 | } |
111 | } | 109 | } |
112 | 110 | ||
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index b09c8d1f9a66..345bd0e0884e 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -441,7 +441,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
441 | void __iomem *base_addr) | 441 | void __iomem *base_addr) |
442 | { | 442 | { |
443 | struct cyclades_port *info; | 443 | struct cyclades_port *info; |
444 | struct tty_struct *tty; | 444 | struct tty_port *port; |
445 | int len, index = cinfo->bus_index; | 445 | int len, index = cinfo->bus_index; |
446 | u8 ivr, save_xir, channel, save_car, data, char_count; | 446 | u8 ivr, save_xir, channel, save_car, data, char_count; |
447 | 447 | ||
@@ -452,22 +452,11 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
452 | save_xir = readb(base_addr + (CyRIR << index)); | 452 | save_xir = readb(base_addr + (CyRIR << index)); |
453 | channel = save_xir & CyIRChannel; | 453 | channel = save_xir & CyIRChannel; |
454 | info = &cinfo->ports[channel + chip * 4]; | 454 | info = &cinfo->ports[channel + chip * 4]; |
455 | port = &info->port; | ||
455 | save_car = cyy_readb(info, CyCAR); | 456 | save_car = cyy_readb(info, CyCAR); |
456 | cyy_writeb(info, CyCAR, save_xir); | 457 | cyy_writeb(info, CyCAR, save_xir); |
457 | ivr = cyy_readb(info, CyRIVR) & CyIVRMask; | 458 | ivr = cyy_readb(info, CyRIVR) & CyIVRMask; |
458 | 459 | ||
459 | tty = tty_port_tty_get(&info->port); | ||
460 | /* if there is nowhere to put the data, discard it */ | ||
461 | if (tty == NULL) { | ||
462 | if (ivr == CyIVRRxEx) { /* exception */ | ||
463 | data = cyy_readb(info, CyRDSR); | ||
464 | } else { /* normal character reception */ | ||
465 | char_count = cyy_readb(info, CyRDCR); | ||
466 | while (char_count--) | ||
467 | data = cyy_readb(info, CyRDSR); | ||
468 | } | ||
469 | goto end; | ||
470 | } | ||
471 | /* there is an open port for this data */ | 460 | /* there is an open port for this data */ |
472 | if (ivr == CyIVRRxEx) { /* exception */ | 461 | if (ivr == CyIVRRxEx) { /* exception */ |
473 | data = cyy_readb(info, CyRDSR); | 462 | data = cyy_readb(info, CyRDSR); |
@@ -484,40 +473,45 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
484 | 473 | ||
485 | if (data & info->ignore_status_mask) { | 474 | if (data & info->ignore_status_mask) { |
486 | info->icount.rx++; | 475 | info->icount.rx++; |
487 | tty_kref_put(tty); | ||
488 | return; | 476 | return; |
489 | } | 477 | } |
490 | if (tty_buffer_request_room(tty, 1)) { | 478 | if (tty_buffer_request_room(port, 1)) { |
491 | if (data & info->read_status_mask) { | 479 | if (data & info->read_status_mask) { |
492 | if (data & CyBREAK) { | 480 | if (data & CyBREAK) { |
493 | tty_insert_flip_char(tty, | 481 | tty_insert_flip_char(port, |
494 | cyy_readb(info, CyRDSR), | 482 | cyy_readb(info, CyRDSR), |
495 | TTY_BREAK); | 483 | TTY_BREAK); |
496 | info->icount.rx++; | 484 | info->icount.rx++; |
497 | if (info->port.flags & ASYNC_SAK) | 485 | if (port->flags & ASYNC_SAK) { |
498 | do_SAK(tty); | 486 | struct tty_struct *tty = |
487 | tty_port_tty_get(port); | ||
488 | if (tty) { | ||
489 | do_SAK(tty); | ||
490 | tty_kref_put(tty); | ||
491 | } | ||
492 | } | ||
499 | } else if (data & CyFRAME) { | 493 | } else if (data & CyFRAME) { |
500 | tty_insert_flip_char(tty, | 494 | tty_insert_flip_char(port, |
501 | cyy_readb(info, CyRDSR), | 495 | cyy_readb(info, CyRDSR), |
502 | TTY_FRAME); | 496 | TTY_FRAME); |
503 | info->icount.rx++; | 497 | info->icount.rx++; |
504 | info->idle_stats.frame_errs++; | 498 | info->idle_stats.frame_errs++; |
505 | } else if (data & CyPARITY) { | 499 | } else if (data & CyPARITY) { |
506 | /* Pieces of seven... */ | 500 | /* Pieces of seven... */ |
507 | tty_insert_flip_char(tty, | 501 | tty_insert_flip_char(port, |
508 | cyy_readb(info, CyRDSR), | 502 | cyy_readb(info, CyRDSR), |
509 | TTY_PARITY); | 503 | TTY_PARITY); |
510 | info->icount.rx++; | 504 | info->icount.rx++; |
511 | info->idle_stats.parity_errs++; | 505 | info->idle_stats.parity_errs++; |
512 | } else if (data & CyOVERRUN) { | 506 | } else if (data & CyOVERRUN) { |
513 | tty_insert_flip_char(tty, 0, | 507 | tty_insert_flip_char(port, 0, |
514 | TTY_OVERRUN); | 508 | TTY_OVERRUN); |
515 | info->icount.rx++; | 509 | info->icount.rx++; |
516 | /* If the flip buffer itself is | 510 | /* If the flip buffer itself is |
517 | overflowing, we still lose | 511 | overflowing, we still lose |
518 | the next incoming character. | 512 | the next incoming character. |
519 | */ | 513 | */ |
520 | tty_insert_flip_char(tty, | 514 | tty_insert_flip_char(port, |
521 | cyy_readb(info, CyRDSR), | 515 | cyy_readb(info, CyRDSR), |
522 | TTY_FRAME); | 516 | TTY_FRAME); |
523 | info->icount.rx++; | 517 | info->icount.rx++; |
@@ -527,12 +521,12 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
527 | /* } else if(data & CyTIMEOUT) { */ | 521 | /* } else if(data & CyTIMEOUT) { */ |
528 | /* } else if(data & CySPECHAR) { */ | 522 | /* } else if(data & CySPECHAR) { */ |
529 | } else { | 523 | } else { |
530 | tty_insert_flip_char(tty, 0, | 524 | tty_insert_flip_char(port, 0, |
531 | TTY_NORMAL); | 525 | TTY_NORMAL); |
532 | info->icount.rx++; | 526 | info->icount.rx++; |
533 | } | 527 | } |
534 | } else { | 528 | } else { |
535 | tty_insert_flip_char(tty, 0, TTY_NORMAL); | 529 | tty_insert_flip_char(port, 0, TTY_NORMAL); |
536 | info->icount.rx++; | 530 | info->icount.rx++; |
537 | } | 531 | } |
538 | } else { | 532 | } else { |
@@ -552,10 +546,10 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
552 | info->mon.char_max = char_count; | 546 | info->mon.char_max = char_count; |
553 | info->mon.char_last = char_count; | 547 | info->mon.char_last = char_count; |
554 | #endif | 548 | #endif |
555 | len = tty_buffer_request_room(tty, char_count); | 549 | len = tty_buffer_request_room(port, char_count); |
556 | while (len--) { | 550 | while (len--) { |
557 | data = cyy_readb(info, CyRDSR); | 551 | data = cyy_readb(info, CyRDSR); |
558 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 552 | tty_insert_flip_char(port, data, TTY_NORMAL); |
559 | info->idle_stats.recv_bytes++; | 553 | info->idle_stats.recv_bytes++; |
560 | info->icount.rx++; | 554 | info->icount.rx++; |
561 | #ifdef CY_16Y_HACK | 555 | #ifdef CY_16Y_HACK |
@@ -564,9 +558,8 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, | |||
564 | } | 558 | } |
565 | info->idle_stats.recv_idle = jiffies; | 559 | info->idle_stats.recv_idle = jiffies; |
566 | } | 560 | } |
567 | tty_schedule_flip(tty); | 561 | tty_schedule_flip(port); |
568 | tty_kref_put(tty); | 562 | |
569 | end: | ||
570 | /* end of service */ | 563 | /* end of service */ |
571 | cyy_writeb(info, CyRIR, save_xir & 0x3f); | 564 | cyy_writeb(info, CyRIR, save_xir & 0x3f); |
572 | cyy_writeb(info, CyCAR, save_car); | 565 | cyy_writeb(info, CyCAR, save_car); |
@@ -924,10 +917,11 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
924 | return 0; | 917 | return 0; |
925 | } /* cyz_issue_cmd */ | 918 | } /* cyz_issue_cmd */ |
926 | 919 | ||
927 | static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) | 920 | static void cyz_handle_rx(struct cyclades_port *info) |
928 | { | 921 | { |
929 | struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; | 922 | struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; |
930 | struct cyclades_card *cinfo = info->card; | 923 | struct cyclades_card *cinfo = info->card; |
924 | struct tty_port *port = &info->port; | ||
931 | unsigned int char_count; | 925 | unsigned int char_count; |
932 | int len; | 926 | int len; |
933 | #ifdef BLOCKMOVE | 927 | #ifdef BLOCKMOVE |
@@ -946,80 +940,77 @@ static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) | |||
946 | else | 940 | else |
947 | char_count = rx_put - rx_get + rx_bufsize; | 941 | char_count = rx_put - rx_get + rx_bufsize; |
948 | 942 | ||
949 | if (char_count) { | 943 | if (!char_count) |
944 | return; | ||
945 | |||
950 | #ifdef CY_ENABLE_MONITORING | 946 | #ifdef CY_ENABLE_MONITORING |
951 | info->mon.int_count++; | 947 | info->mon.int_count++; |
952 | info->mon.char_count += char_count; | 948 | info->mon.char_count += char_count; |
953 | if (char_count > info->mon.char_max) | 949 | if (char_count > info->mon.char_max) |
954 | info->mon.char_max = char_count; | 950 | info->mon.char_max = char_count; |
955 | info->mon.char_last = char_count; | 951 | info->mon.char_last = char_count; |
956 | #endif | 952 | #endif |
957 | if (tty == NULL) { | 953 | |
958 | /* flush received characters */ | ||
959 | new_rx_get = (new_rx_get + char_count) & | ||
960 | (rx_bufsize - 1); | ||
961 | info->rflush_count++; | ||
962 | } else { | ||
963 | #ifdef BLOCKMOVE | 954 | #ifdef BLOCKMOVE |
964 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) | 955 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) |
965 | for performance, but because of buffer boundaries, there | 956 | for performance, but because of buffer boundaries, there |
966 | may be several steps to the operation */ | 957 | may be several steps to the operation */ |
967 | while (1) { | 958 | while (1) { |
968 | len = tty_prepare_flip_string(tty, &buf, | 959 | len = tty_prepare_flip_string(port, &buf, |
969 | char_count); | 960 | char_count); |
970 | if (!len) | 961 | if (!len) |
971 | break; | 962 | break; |
972 | 963 | ||
973 | len = min_t(unsigned int, min(len, char_count), | 964 | len = min_t(unsigned int, min(len, char_count), |
974 | rx_bufsize - new_rx_get); | 965 | rx_bufsize - new_rx_get); |
975 | 966 | ||
976 | memcpy_fromio(buf, cinfo->base_addr + | 967 | memcpy_fromio(buf, cinfo->base_addr + |
977 | rx_bufaddr + new_rx_get, len); | 968 | rx_bufaddr + new_rx_get, len); |
978 | 969 | ||
979 | new_rx_get = (new_rx_get + len) & | 970 | new_rx_get = (new_rx_get + len) & |
980 | (rx_bufsize - 1); | 971 | (rx_bufsize - 1); |
981 | char_count -= len; | 972 | char_count -= len; |
982 | info->icount.rx += len; | 973 | info->icount.rx += len; |
983 | info->idle_stats.recv_bytes += len; | 974 | info->idle_stats.recv_bytes += len; |
984 | } | 975 | } |
985 | #else | 976 | #else |
986 | len = tty_buffer_request_room(tty, char_count); | 977 | len = tty_buffer_request_room(port, char_count); |
987 | while (len--) { | 978 | while (len--) { |
988 | data = readb(cinfo->base_addr + rx_bufaddr + | 979 | data = readb(cinfo->base_addr + rx_bufaddr + |
989 | new_rx_get); | 980 | new_rx_get); |
990 | new_rx_get = (new_rx_get + 1) & | 981 | new_rx_get = (new_rx_get + 1) & |
991 | (rx_bufsize - 1); | 982 | (rx_bufsize - 1); |
992 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 983 | tty_insert_flip_char(port, data, TTY_NORMAL); |
993 | info->idle_stats.recv_bytes++; | 984 | info->idle_stats.recv_bytes++; |
994 | info->icount.rx++; | 985 | info->icount.rx++; |
995 | } | 986 | } |
996 | #endif | 987 | #endif |
997 | #ifdef CONFIG_CYZ_INTR | 988 | #ifdef CONFIG_CYZ_INTR |
998 | /* Recalculate the number of chars in the RX buffer and issue | 989 | /* Recalculate the number of chars in the RX buffer and issue |
999 | a cmd in case it's higher than the RX high water mark */ | 990 | a cmd in case it's higher than the RX high water mark */ |
1000 | rx_put = readl(&buf_ctrl->rx_put); | 991 | rx_put = readl(&buf_ctrl->rx_put); |
1001 | if (rx_put >= rx_get) | 992 | if (rx_put >= rx_get) |
1002 | char_count = rx_put - rx_get; | 993 | char_count = rx_put - rx_get; |
1003 | else | 994 | else |
1004 | char_count = rx_put - rx_get + rx_bufsize; | 995 | char_count = rx_put - rx_get + rx_bufsize; |
1005 | if (char_count >= readl(&buf_ctrl->rx_threshold) && | 996 | if (char_count >= readl(&buf_ctrl->rx_threshold) && |
1006 | !timer_pending(&cyz_rx_full_timer[ | 997 | !timer_pending(&cyz_rx_full_timer[ |
1007 | info->line])) | 998 | info->line])) |
1008 | mod_timer(&cyz_rx_full_timer[info->line], | 999 | mod_timer(&cyz_rx_full_timer[info->line], |
1009 | jiffies + 1); | 1000 | jiffies + 1); |
1010 | #endif | 1001 | #endif |
1011 | info->idle_stats.recv_idle = jiffies; | 1002 | info->idle_stats.recv_idle = jiffies; |
1012 | tty_schedule_flip(tty); | 1003 | tty_schedule_flip(&info->port); |
1013 | } | 1004 | |
1014 | /* Update rx_get */ | 1005 | /* Update rx_get */ |
1015 | cy_writel(&buf_ctrl->rx_get, new_rx_get); | 1006 | cy_writel(&buf_ctrl->rx_get, new_rx_get); |
1016 | } | ||
1017 | } | 1007 | } |
1018 | 1008 | ||
1019 | static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) | 1009 | static void cyz_handle_tx(struct cyclades_port *info) |
1020 | { | 1010 | { |
1021 | struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; | 1011 | struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; |
1022 | struct cyclades_card *cinfo = info->card; | 1012 | struct cyclades_card *cinfo = info->card; |
1013 | struct tty_struct *tty; | ||
1023 | u8 data; | 1014 | u8 data; |
1024 | unsigned int char_count; | 1015 | unsigned int char_count; |
1025 | #ifdef BLOCKMOVE | 1016 | #ifdef BLOCKMOVE |
@@ -1039,63 +1030,63 @@ static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) | |||
1039 | else | 1030 | else |
1040 | char_count = tx_get - tx_put - 1; | 1031 | char_count = tx_get - tx_put - 1; |
1041 | 1032 | ||
1042 | if (char_count) { | 1033 | if (!char_count) |
1043 | 1034 | return; | |
1044 | if (tty == NULL) | 1035 | |
1045 | goto ztxdone; | 1036 | tty = tty_port_tty_get(&info->port); |
1037 | if (tty == NULL) | ||
1038 | goto ztxdone; | ||
1046 | 1039 | ||
1047 | if (info->x_char) { /* send special char */ | 1040 | if (info->x_char) { /* send special char */ |
1048 | data = info->x_char; | 1041 | data = info->x_char; |
1049 | 1042 | ||
1050 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); | 1043 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); |
1051 | tx_put = (tx_put + 1) & (tx_bufsize - 1); | 1044 | tx_put = (tx_put + 1) & (tx_bufsize - 1); |
1052 | info->x_char = 0; | 1045 | info->x_char = 0; |
1053 | char_count--; | 1046 | char_count--; |
1054 | info->icount.tx++; | 1047 | info->icount.tx++; |
1055 | } | 1048 | } |
1056 | #ifdef BLOCKMOVE | 1049 | #ifdef BLOCKMOVE |
1057 | while (0 < (small_count = min_t(unsigned int, | 1050 | while (0 < (small_count = min_t(unsigned int, |
1058 | tx_bufsize - tx_put, min_t(unsigned int, | 1051 | tx_bufsize - tx_put, min_t(unsigned int, |
1059 | (SERIAL_XMIT_SIZE - info->xmit_tail), | 1052 | (SERIAL_XMIT_SIZE - info->xmit_tail), |
1060 | min_t(unsigned int, info->xmit_cnt, | 1053 | min_t(unsigned int, info->xmit_cnt, |
1061 | char_count))))) { | 1054 | char_count))))) { |
1062 | 1055 | ||
1063 | memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + | 1056 | memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put), |
1064 | tx_put), | 1057 | &info->port.xmit_buf[info->xmit_tail], |
1065 | &info->port.xmit_buf[info->xmit_tail], | 1058 | small_count); |
1066 | small_count); | 1059 | |
1067 | 1060 | tx_put = (tx_put + small_count) & (tx_bufsize - 1); | |
1068 | tx_put = (tx_put + small_count) & (tx_bufsize - 1); | 1061 | char_count -= small_count; |
1069 | char_count -= small_count; | 1062 | info->icount.tx += small_count; |
1070 | info->icount.tx += small_count; | 1063 | info->xmit_cnt -= small_count; |
1071 | info->xmit_cnt -= small_count; | 1064 | info->xmit_tail = (info->xmit_tail + small_count) & |
1072 | info->xmit_tail = (info->xmit_tail + small_count) & | 1065 | (SERIAL_XMIT_SIZE - 1); |
1073 | (SERIAL_XMIT_SIZE - 1); | 1066 | } |
1074 | } | ||
1075 | #else | 1067 | #else |
1076 | while (info->xmit_cnt && char_count) { | 1068 | while (info->xmit_cnt && char_count) { |
1077 | data = info->port.xmit_buf[info->xmit_tail]; | 1069 | data = info->port.xmit_buf[info->xmit_tail]; |
1078 | info->xmit_cnt--; | 1070 | info->xmit_cnt--; |
1079 | info->xmit_tail = (info->xmit_tail + 1) & | 1071 | info->xmit_tail = (info->xmit_tail + 1) & |
1080 | (SERIAL_XMIT_SIZE - 1); | 1072 | (SERIAL_XMIT_SIZE - 1); |
1081 | 1073 | ||
1082 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); | 1074 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); |
1083 | tx_put = (tx_put + 1) & (tx_bufsize - 1); | 1075 | tx_put = (tx_put + 1) & (tx_bufsize - 1); |
1084 | char_count--; | 1076 | char_count--; |
1085 | info->icount.tx++; | 1077 | info->icount.tx++; |
1086 | } | 1078 | } |
1087 | #endif | 1079 | #endif |
1088 | tty_wakeup(tty); | 1080 | tty_wakeup(tty); |
1081 | tty_kref_put(tty); | ||
1089 | ztxdone: | 1082 | ztxdone: |
1090 | /* Update tx_put */ | 1083 | /* Update tx_put */ |
1091 | cy_writel(&buf_ctrl->tx_put, tx_put); | 1084 | cy_writel(&buf_ctrl->tx_put, tx_put); |
1092 | } | ||
1093 | } | 1085 | } |
1094 | 1086 | ||
1095 | static void cyz_handle_cmd(struct cyclades_card *cinfo) | 1087 | static void cyz_handle_cmd(struct cyclades_card *cinfo) |
1096 | { | 1088 | { |
1097 | struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; | 1089 | struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; |
1098 | struct tty_struct *tty; | ||
1099 | struct cyclades_port *info; | 1090 | struct cyclades_port *info; |
1100 | __u32 channel, param, fw_ver; | 1091 | __u32 channel, param, fw_ver; |
1101 | __u8 cmd; | 1092 | __u8 cmd; |
@@ -1108,23 +1099,20 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1108 | special_count = 0; | 1099 | special_count = 0; |
1109 | delta_count = 0; | 1100 | delta_count = 0; |
1110 | info = &cinfo->ports[channel]; | 1101 | info = &cinfo->ports[channel]; |
1111 | tty = tty_port_tty_get(&info->port); | ||
1112 | if (tty == NULL) | ||
1113 | continue; | ||
1114 | 1102 | ||
1115 | switch (cmd) { | 1103 | switch (cmd) { |
1116 | case C_CM_PR_ERROR: | 1104 | case C_CM_PR_ERROR: |
1117 | tty_insert_flip_char(tty, 0, TTY_PARITY); | 1105 | tty_insert_flip_char(&info->port, 0, TTY_PARITY); |
1118 | info->icount.rx++; | 1106 | info->icount.rx++; |
1119 | special_count++; | 1107 | special_count++; |
1120 | break; | 1108 | break; |
1121 | case C_CM_FR_ERROR: | 1109 | case C_CM_FR_ERROR: |
1122 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 1110 | tty_insert_flip_char(&info->port, 0, TTY_FRAME); |
1123 | info->icount.rx++; | 1111 | info->icount.rx++; |
1124 | special_count++; | 1112 | special_count++; |
1125 | break; | 1113 | break; |
1126 | case C_CM_RXBRK: | 1114 | case C_CM_RXBRK: |
1127 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1115 | tty_insert_flip_char(&info->port, 0, TTY_BREAK); |
1128 | info->icount.rx++; | 1116 | info->icount.rx++; |
1129 | special_count++; | 1117 | special_count++; |
1130 | break; | 1118 | break; |
@@ -1136,8 +1124,14 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1136 | readl(&info->u.cyz.ch_ctrl->rs_status); | 1124 | readl(&info->u.cyz.ch_ctrl->rs_status); |
1137 | if (dcd & C_RS_DCD) | 1125 | if (dcd & C_RS_DCD) |
1138 | wake_up_interruptible(&info->port.open_wait); | 1126 | wake_up_interruptible(&info->port.open_wait); |
1139 | else | 1127 | else { |
1140 | tty_hangup(tty); | 1128 | struct tty_struct *tty; |
1129 | tty = tty_port_tty_get(&info->port); | ||
1130 | if (tty) { | ||
1131 | tty_hangup(tty); | ||
1132 | tty_kref_put(tty); | ||
1133 | } | ||
1134 | } | ||
1141 | } | 1135 | } |
1142 | break; | 1136 | break; |
1143 | case C_CM_MCTS: | 1137 | case C_CM_MCTS: |
@@ -1166,7 +1160,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1166 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " | 1160 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " |
1167 | "port %ld\n", info->card, channel); | 1161 | "port %ld\n", info->card, channel); |
1168 | #endif | 1162 | #endif |
1169 | cyz_handle_rx(info, tty); | 1163 | cyz_handle_rx(info); |
1170 | break; | 1164 | break; |
1171 | case C_CM_TXBEMPTY: | 1165 | case C_CM_TXBEMPTY: |
1172 | case C_CM_TXLOWWM: | 1166 | case C_CM_TXLOWWM: |
@@ -1176,7 +1170,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1176 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " | 1170 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " |
1177 | "port %ld\n", info->card, channel); | 1171 | "port %ld\n", info->card, channel); |
1178 | #endif | 1172 | #endif |
1179 | cyz_handle_tx(info, tty); | 1173 | cyz_handle_tx(info); |
1180 | break; | 1174 | break; |
1181 | #endif /* CONFIG_CYZ_INTR */ | 1175 | #endif /* CONFIG_CYZ_INTR */ |
1182 | case C_CM_FATAL: | 1176 | case C_CM_FATAL: |
@@ -1188,8 +1182,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1188 | if (delta_count) | 1182 | if (delta_count) |
1189 | wake_up_interruptible(&info->port.delta_msr_wait); | 1183 | wake_up_interruptible(&info->port.delta_msr_wait); |
1190 | if (special_count) | 1184 | if (special_count) |
1191 | tty_schedule_flip(tty); | 1185 | tty_schedule_flip(&info->port); |
1192 | tty_kref_put(tty); | ||
1193 | } | 1186 | } |
1194 | } | 1187 | } |
1195 | 1188 | ||
@@ -1255,17 +1248,11 @@ static void cyz_poll(unsigned long arg) | |||
1255 | cyz_handle_cmd(cinfo); | 1248 | cyz_handle_cmd(cinfo); |
1256 | 1249 | ||
1257 | for (port = 0; port < cinfo->nports; port++) { | 1250 | for (port = 0; port < cinfo->nports; port++) { |
1258 | struct tty_struct *tty; | ||
1259 | |||
1260 | info = &cinfo->ports[port]; | 1251 | info = &cinfo->ports[port]; |
1261 | tty = tty_port_tty_get(&info->port); | ||
1262 | /* OK to pass NULL to the handle functions below. | ||
1263 | They need to drop the data in that case. */ | ||
1264 | 1252 | ||
1265 | if (!info->throttle) | 1253 | if (!info->throttle) |
1266 | cyz_handle_rx(info, tty); | 1254 | cyz_handle_rx(info); |
1267 | cyz_handle_tx(info, tty); | 1255 | cyz_handle_tx(info); |
1268 | tty_kref_put(tty); | ||
1269 | } | 1256 | } |
1270 | /* poll every 'cyz_polling_cycle' period */ | 1257 | /* poll every 'cyz_polling_cycle' period */ |
1271 | expires = jiffies + cyz_polling_cycle; | 1258 | expires = jiffies + cyz_polling_cycle; |
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index c117d775a22f..ed92622b8949 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
@@ -371,22 +371,17 @@ console_initcall(ehv_bc_console_init); | |||
371 | static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) | 371 | static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) |
372 | { | 372 | { |
373 | struct ehv_bc_data *bc = data; | 373 | struct ehv_bc_data *bc = data; |
374 | struct tty_struct *ttys = tty_port_tty_get(&bc->port); | ||
375 | unsigned int rx_count, tx_count, len; | 374 | unsigned int rx_count, tx_count, len; |
376 | int count; | 375 | int count; |
377 | char buffer[EV_BYTE_CHANNEL_MAX_BYTES]; | 376 | char buffer[EV_BYTE_CHANNEL_MAX_BYTES]; |
378 | int ret; | 377 | int ret; |
379 | 378 | ||
380 | /* ttys could be NULL during a hangup */ | ||
381 | if (!ttys) | ||
382 | return IRQ_HANDLED; | ||
383 | |||
384 | /* Find out how much data needs to be read, and then ask the TTY layer | 379 | /* Find out how much data needs to be read, and then ask the TTY layer |
385 | * if it can handle that much. We want to ensure that every byte we | 380 | * if it can handle that much. We want to ensure that every byte we |
386 | * read from the byte channel will be accepted by the TTY layer. | 381 | * read from the byte channel will be accepted by the TTY layer. |
387 | */ | 382 | */ |
388 | ev_byte_channel_poll(bc->handle, &rx_count, &tx_count); | 383 | ev_byte_channel_poll(bc->handle, &rx_count, &tx_count); |
389 | count = tty_buffer_request_room(ttys, rx_count); | 384 | count = tty_buffer_request_room(&bc->port, rx_count); |
390 | 385 | ||
391 | /* 'count' is the maximum amount of data the TTY layer can accept at | 386 | /* 'count' is the maximum amount of data the TTY layer can accept at |
392 | * this time. However, during testing, I was never able to get 'count' | 387 | * this time. However, during testing, I was never able to get 'count' |
@@ -407,7 +402,7 @@ static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) | |||
407 | */ | 402 | */ |
408 | 403 | ||
409 | /* Pass the received data to the tty layer. */ | 404 | /* Pass the received data to the tty layer. */ |
410 | ret = tty_insert_flip_string(ttys, buffer, len); | 405 | ret = tty_insert_flip_string(&bc->port, buffer, len); |
411 | 406 | ||
412 | /* 'ret' is the number of bytes that the TTY layer accepted. | 407 | /* 'ret' is the number of bytes that the TTY layer accepted. |
413 | * If it's not equal to 'len', then it means the buffer is | 408 | * If it's not equal to 'len', then it means the buffer is |
@@ -422,9 +417,7 @@ static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data) | |||
422 | } | 417 | } |
423 | 418 | ||
424 | /* Tell the tty layer that we're done. */ | 419 | /* Tell the tty layer that we're done. */ |
425 | tty_flip_buffer_push(ttys); | 420 | tty_flip_buffer_push(&bc->port); |
426 | |||
427 | tty_kref_put(ttys); | ||
428 | 421 | ||
429 | return IRQ_HANDLED; | 422 | return IRQ_HANDLED; |
430 | } | 423 | } |
diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c new file mode 100644 index 000000000000..f17d2e4ee2ca --- /dev/null +++ b/drivers/tty/goldfish.c | |||
@@ -0,0 +1,328 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 Google, Inc. | ||
3 | * Copyright (C) 2012 Intel, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/console.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/tty.h> | ||
21 | #include <linux/tty_flip.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/module.h> | ||
25 | |||
26 | enum { | ||
27 | GOLDFISH_TTY_PUT_CHAR = 0x00, | ||
28 | GOLDFISH_TTY_BYTES_READY = 0x04, | ||
29 | GOLDFISH_TTY_CMD = 0x08, | ||
30 | |||
31 | GOLDFISH_TTY_DATA_PTR = 0x10, | ||
32 | GOLDFISH_TTY_DATA_LEN = 0x14, | ||
33 | |||
34 | GOLDFISH_TTY_CMD_INT_DISABLE = 0, | ||
35 | GOLDFISH_TTY_CMD_INT_ENABLE = 1, | ||
36 | GOLDFISH_TTY_CMD_WRITE_BUFFER = 2, | ||
37 | GOLDFISH_TTY_CMD_READ_BUFFER = 3, | ||
38 | }; | ||
39 | |||
40 | struct goldfish_tty { | ||
41 | struct tty_port port; | ||
42 | spinlock_t lock; | ||
43 | void __iomem *base; | ||
44 | u32 irq; | ||
45 | int opencount; | ||
46 | struct console console; | ||
47 | }; | ||
48 | |||
49 | static DEFINE_MUTEX(goldfish_tty_lock); | ||
50 | static struct tty_driver *goldfish_tty_driver; | ||
51 | static u32 goldfish_tty_line_count = 8; | ||
52 | static u32 goldfish_tty_current_line_count; | ||
53 | static struct goldfish_tty *goldfish_ttys; | ||
54 | |||
55 | static void goldfish_tty_do_write(int line, const char *buf, unsigned count) | ||
56 | { | ||
57 | unsigned long irq_flags; | ||
58 | struct goldfish_tty *qtty = &goldfish_ttys[line]; | ||
59 | void __iomem *base = qtty->base; | ||
60 | spin_lock_irqsave(&qtty->lock, irq_flags); | ||
61 | writel((u32)buf, base + GOLDFISH_TTY_DATA_PTR); | ||
62 | writel(count, base + GOLDFISH_TTY_DATA_LEN); | ||
63 | writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, base + GOLDFISH_TTY_CMD); | ||
64 | spin_unlock_irqrestore(&qtty->lock, irq_flags); | ||
65 | } | ||
66 | |||
67 | static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) | ||
68 | { | ||
69 | struct platform_device *pdev = dev_id; | ||
70 | struct goldfish_tty *qtty = &goldfish_ttys[pdev->id]; | ||
71 | void __iomem *base = qtty->base; | ||
72 | unsigned long irq_flags; | ||
73 | unsigned char *buf; | ||
74 | u32 count; | ||
75 | |||
76 | count = readl(base + GOLDFISH_TTY_BYTES_READY); | ||
77 | if(count == 0) | ||
78 | return IRQ_NONE; | ||
79 | |||
80 | count = tty_prepare_flip_string(&qtty->port, &buf, count); | ||
81 | spin_lock_irqsave(&qtty->lock, irq_flags); | ||
82 | writel((u32)buf, base + GOLDFISH_TTY_DATA_PTR); | ||
83 | writel(count, base + GOLDFISH_TTY_DATA_LEN); | ||
84 | writel(GOLDFISH_TTY_CMD_READ_BUFFER, base + GOLDFISH_TTY_CMD); | ||
85 | spin_unlock_irqrestore(&qtty->lock, irq_flags); | ||
86 | tty_schedule_flip(&qtty->port); | ||
87 | return IRQ_HANDLED; | ||
88 | } | ||
89 | |||
90 | static int goldfish_tty_activate(struct tty_port *port, struct tty_struct *tty) | ||
91 | { | ||
92 | struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); | ||
93 | writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_CMD); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static void goldfish_tty_shutdown(struct tty_port *port) | ||
98 | { | ||
99 | struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); | ||
100 | writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_CMD); | ||
101 | } | ||
102 | |||
103 | static int goldfish_tty_open(struct tty_struct * tty, struct file * filp) | ||
104 | { | ||
105 | struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; | ||
106 | return tty_port_open(&qtty->port, tty, filp); | ||
107 | } | ||
108 | |||
109 | static void goldfish_tty_close(struct tty_struct * tty, struct file * filp) | ||
110 | { | ||
111 | tty_port_close(tty->port, tty, filp); | ||
112 | } | ||
113 | |||
114 | static void goldfish_tty_hangup(struct tty_struct *tty) | ||
115 | { | ||
116 | tty_port_hangup(tty->port); | ||
117 | } | ||
118 | |||
119 | static int goldfish_tty_write(struct tty_struct * tty, const unsigned char *buf, int count) | ||
120 | { | ||
121 | goldfish_tty_do_write(tty->index, buf, count); | ||
122 | return count; | ||
123 | } | ||
124 | |||
125 | static int goldfish_tty_write_room(struct tty_struct *tty) | ||
126 | { | ||
127 | return 0x10000; | ||
128 | } | ||
129 | |||
130 | static int goldfish_tty_chars_in_buffer(struct tty_struct *tty) | ||
131 | { | ||
132 | struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; | ||
133 | void __iomem *base = qtty->base; | ||
134 | return readl(base + GOLDFISH_TTY_BYTES_READY); | ||
135 | } | ||
136 | |||
137 | static void goldfish_tty_console_write(struct console *co, const char *b, unsigned count) | ||
138 | { | ||
139 | goldfish_tty_do_write(co->index, b, count); | ||
140 | } | ||
141 | |||
142 | static struct tty_driver *goldfish_tty_console_device(struct console *c, int *index) | ||
143 | { | ||
144 | *index = c->index; | ||
145 | return goldfish_tty_driver; | ||
146 | } | ||
147 | |||
148 | static int goldfish_tty_console_setup(struct console *co, char *options) | ||
149 | { | ||
150 | if((unsigned)co->index > goldfish_tty_line_count) | ||
151 | return -ENODEV; | ||
152 | if(goldfish_ttys[co->index].base == 0) | ||
153 | return -ENODEV; | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static struct tty_port_operations goldfish_port_ops = { | ||
158 | .activate = goldfish_tty_activate, | ||
159 | .shutdown = goldfish_tty_shutdown | ||
160 | }; | ||
161 | |||
162 | static struct tty_operations goldfish_tty_ops = { | ||
163 | .open = goldfish_tty_open, | ||
164 | .close = goldfish_tty_close, | ||
165 | .hangup = goldfish_tty_hangup, | ||
166 | .write = goldfish_tty_write, | ||
167 | .write_room = goldfish_tty_write_room, | ||
168 | .chars_in_buffer = goldfish_tty_chars_in_buffer, | ||
169 | }; | ||
170 | |||
171 | static int goldfish_tty_create_driver(void) | ||
172 | { | ||
173 | int ret; | ||
174 | struct tty_driver *tty; | ||
175 | |||
176 | goldfish_ttys = kzalloc(sizeof(*goldfish_ttys) * goldfish_tty_line_count, GFP_KERNEL); | ||
177 | if(goldfish_ttys == NULL) { | ||
178 | ret = -ENOMEM; | ||
179 | goto err_alloc_goldfish_ttys_failed; | ||
180 | } | ||
181 | tty = alloc_tty_driver(goldfish_tty_line_count); | ||
182 | if(tty == NULL) { | ||
183 | ret = -ENOMEM; | ||
184 | goto err_alloc_tty_driver_failed; | ||
185 | } | ||
186 | tty->driver_name = "goldfish"; | ||
187 | tty->name = "ttyGF"; | ||
188 | tty->type = TTY_DRIVER_TYPE_SERIAL; | ||
189 | tty->subtype = SERIAL_TYPE_NORMAL; | ||
190 | tty->init_termios = tty_std_termios; | ||
191 | tty->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
192 | tty_set_operations(tty, &goldfish_tty_ops); | ||
193 | ret = tty_register_driver(tty); | ||
194 | if(ret) | ||
195 | goto err_tty_register_driver_failed; | ||
196 | |||
197 | goldfish_tty_driver = tty; | ||
198 | return 0; | ||
199 | |||
200 | err_tty_register_driver_failed: | ||
201 | put_tty_driver(tty); | ||
202 | err_alloc_tty_driver_failed: | ||
203 | kfree(goldfish_ttys); | ||
204 | goldfish_ttys = NULL; | ||
205 | err_alloc_goldfish_ttys_failed: | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static void goldfish_tty_delete_driver(void) | ||
210 | { | ||
211 | tty_unregister_driver(goldfish_tty_driver); | ||
212 | put_tty_driver(goldfish_tty_driver); | ||
213 | goldfish_tty_driver = NULL; | ||
214 | kfree(goldfish_ttys); | ||
215 | goldfish_ttys = NULL; | ||
216 | } | ||
217 | |||
218 | static int goldfish_tty_probe(struct platform_device *pdev) | ||
219 | { | ||
220 | struct goldfish_tty *qtty; | ||
221 | int ret = -EINVAL; | ||
222 | int i; | ||
223 | struct resource *r; | ||
224 | struct device *ttydev; | ||
225 | void __iomem *base; | ||
226 | u32 irq; | ||
227 | |||
228 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
229 | if(r == NULL) | ||
230 | return -EINVAL; | ||
231 | |||
232 | base = ioremap(r->start, 0x1000); | ||
233 | if (base == NULL) | ||
234 | pr_err("goldfish_tty: unable to remap base\n"); | ||
235 | |||
236 | r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
237 | if(r == NULL) | ||
238 | goto err_unmap; | ||
239 | |||
240 | irq = r->start; | ||
241 | |||
242 | if(pdev->id >= goldfish_tty_line_count) | ||
243 | goto err_unmap; | ||
244 | |||
245 | mutex_lock(&goldfish_tty_lock); | ||
246 | if(goldfish_tty_current_line_count == 0) { | ||
247 | ret = goldfish_tty_create_driver(); | ||
248 | if(ret) | ||
249 | goto err_create_driver_failed; | ||
250 | } | ||
251 | goldfish_tty_current_line_count++; | ||
252 | |||
253 | qtty = &goldfish_ttys[pdev->id]; | ||
254 | spin_lock_init(&qtty->lock); | ||
255 | tty_port_init(&qtty->port); | ||
256 | qtty->port.ops = &goldfish_port_ops; | ||
257 | qtty->base = base; | ||
258 | qtty->irq = irq; | ||
259 | |||
260 | writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_CMD); | ||
261 | |||
262 | ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED, "goldfish_tty", pdev); | ||
263 | if(ret) | ||
264 | goto err_request_irq_failed; | ||
265 | |||
266 | |||
267 | ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver, | ||
268 | pdev->id, &pdev->dev); | ||
269 | if(IS_ERR(ttydev)) { | ||
270 | ret = PTR_ERR(ttydev); | ||
271 | goto err_tty_register_device_failed; | ||
272 | } | ||
273 | |||
274 | strcpy(qtty->console.name, "ttyGF"); | ||
275 | qtty->console.write = goldfish_tty_console_write; | ||
276 | qtty->console.device = goldfish_tty_console_device; | ||
277 | qtty->console.setup = goldfish_tty_console_setup; | ||
278 | qtty->console.flags = CON_PRINTBUFFER; | ||
279 | qtty->console.index = pdev->id; | ||
280 | register_console(&qtty->console); | ||
281 | |||
282 | mutex_unlock(&goldfish_tty_lock); | ||
283 | return 0; | ||
284 | |||
285 | tty_unregister_device(goldfish_tty_driver, i); | ||
286 | err_tty_register_device_failed: | ||
287 | free_irq(irq, pdev); | ||
288 | err_request_irq_failed: | ||
289 | goldfish_tty_current_line_count--; | ||
290 | if(goldfish_tty_current_line_count == 0) | ||
291 | goldfish_tty_delete_driver(); | ||
292 | err_create_driver_failed: | ||
293 | mutex_unlock(&goldfish_tty_lock); | ||
294 | err_unmap: | ||
295 | iounmap(base); | ||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | static int goldfish_tty_remove(struct platform_device *pdev) | ||
300 | { | ||
301 | struct goldfish_tty *qtty; | ||
302 | |||
303 | mutex_lock(&goldfish_tty_lock); | ||
304 | |||
305 | qtty = &goldfish_ttys[pdev->id]; | ||
306 | unregister_console(&qtty->console); | ||
307 | tty_unregister_device(goldfish_tty_driver, pdev->id); | ||
308 | iounmap(qtty->base); | ||
309 | qtty->base = 0; | ||
310 | free_irq(qtty->irq, pdev); | ||
311 | goldfish_tty_current_line_count--; | ||
312 | if(goldfish_tty_current_line_count == 0) | ||
313 | goldfish_tty_delete_driver(); | ||
314 | mutex_unlock(&goldfish_tty_lock); | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static struct platform_driver goldfish_tty_platform_driver = { | ||
319 | .probe = goldfish_tty_probe, | ||
320 | .remove = goldfish_tty_remove, | ||
321 | .driver = { | ||
322 | .name = "goldfish_tty" | ||
323 | } | ||
324 | }; | ||
325 | |||
326 | module_platform_driver(goldfish_tty_platform_driver); | ||
327 | |||
328 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index f47b734c6a7a..8902f9b4df71 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig | |||
@@ -1,3 +1,5 @@ | |||
1 | if TTY | ||
2 | |||
1 | config HVC_DRIVER | 3 | config HVC_DRIVER |
2 | bool | 4 | bool |
3 | help | 5 | help |
@@ -119,3 +121,4 @@ config HVCS | |||
119 | which will also be compiled when this driver is built as a | 121 | which will also be compiled when this driver is built as a |
120 | module. | 122 | module. |
121 | 123 | ||
124 | endif # TTY | ||
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 13ee53bd0bf6..eb255e807c06 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
@@ -629,7 +629,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
629 | 629 | ||
630 | /* Read data if any */ | 630 | /* Read data if any */ |
631 | for (;;) { | 631 | for (;;) { |
632 | int count = tty_buffer_request_room(tty, N_INBUF); | 632 | int count = tty_buffer_request_room(&hp->port, N_INBUF); |
633 | 633 | ||
634 | /* If flip is full, just reschedule a later read */ | 634 | /* If flip is full, just reschedule a later read */ |
635 | if (count == 0) { | 635 | if (count == 0) { |
@@ -672,7 +672,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
672 | } | 672 | } |
673 | } | 673 | } |
674 | #endif /* CONFIG_MAGIC_SYSRQ */ | 674 | #endif /* CONFIG_MAGIC_SYSRQ */ |
675 | tty_insert_flip_char(tty, buf[i], 0); | 675 | tty_insert_flip_char(&hp->port, buf[i], 0); |
676 | } | 676 | } |
677 | 677 | ||
678 | read_total += n; | 678 | read_total += n; |
@@ -691,7 +691,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
691 | a minimum for performance. */ | 691 | a minimum for performance. */ |
692 | timeout = MIN_TIMEOUT; | 692 | timeout = MIN_TIMEOUT; |
693 | 693 | ||
694 | tty_flip_buffer_push(tty); | 694 | tty_flip_buffer_push(&hp->port); |
695 | } | 695 | } |
696 | tty_kref_put(tty); | 696 | tty_kref_put(tty); |
697 | 697 | ||
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 877635733952..1956593ee89d 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
@@ -609,11 +609,11 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
609 | /* remove the read masks */ | 609 | /* remove the read masks */ |
610 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); | 610 | hvcsd->todo_mask &= ~(HVCS_READ_MASK); |
611 | 611 | ||
612 | if (tty_buffer_request_room(tty, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) { | 612 | if (tty_buffer_request_room(&hvcsd->port, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) { |
613 | got = hvc_get_chars(unit_address, | 613 | got = hvc_get_chars(unit_address, |
614 | &buf[0], | 614 | &buf[0], |
615 | HVCS_BUFF_LEN); | 615 | HVCS_BUFF_LEN); |
616 | tty_insert_flip_string(tty, buf, got); | 616 | tty_insert_flip_string(&hvcsd->port, buf, got); |
617 | } | 617 | } |
618 | 618 | ||
619 | /* Give the TTY time to process the data we just sent. */ | 619 | /* Give the TTY time to process the data we just sent. */ |
@@ -623,7 +623,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd) | |||
623 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 623 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
624 | /* This is synch because tty->low_latency == 1 */ | 624 | /* This is synch because tty->low_latency == 1 */ |
625 | if(got) | 625 | if(got) |
626 | tty_flip_buffer_push(tty); | 626 | tty_flip_buffer_push(&hvcsd->port); |
627 | 627 | ||
628 | if (!got) { | 628 | if (!got) { |
629 | /* Do this _after_ the flip_buffer_push */ | 629 | /* Do this _after_ the flip_buffer_push */ |
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 68357a6e4de9..ef95a154854a 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c | |||
@@ -329,8 +329,7 @@ static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet) | |||
329 | } | 329 | } |
330 | } | 330 | } |
331 | 331 | ||
332 | static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty, | 332 | static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) |
333 | const char *buf, int len) | ||
334 | { | 333 | { |
335 | int i; | 334 | int i; |
336 | 335 | ||
@@ -346,7 +345,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty, | |||
346 | continue; | 345 | continue; |
347 | } | 346 | } |
348 | #endif /* CONFIG_MAGIC_SYSRQ */ | 347 | #endif /* CONFIG_MAGIC_SYSRQ */ |
349 | tty_insert_flip_char(tty, c, 0); | 348 | tty_insert_flip_char(&hp->port, c, 0); |
350 | } | 349 | } |
351 | } | 350 | } |
352 | 351 | ||
@@ -359,8 +358,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty, | |||
359 | * revisited. | 358 | * revisited. |
360 | */ | 359 | */ |
361 | #define TTY_THRESHOLD_THROTTLE 128 | 360 | #define TTY_THRESHOLD_THROTTLE 128 |
362 | static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty, | 361 | static bool hvsi_recv_data(struct hvsi_struct *hp, const uint8_t *packet) |
363 | const uint8_t *packet) | ||
364 | { | 362 | { |
365 | const struct hvsi_header *header = (const struct hvsi_header *)packet; | 363 | const struct hvsi_header *header = (const struct hvsi_header *)packet; |
366 | const uint8_t *data = packet + sizeof(struct hvsi_header); | 364 | const uint8_t *data = packet + sizeof(struct hvsi_header); |
@@ -377,7 +375,7 @@ static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty, | |||
377 | datalen = TTY_THRESHOLD_THROTTLE; | 375 | datalen = TTY_THRESHOLD_THROTTLE; |
378 | } | 376 | } |
379 | 377 | ||
380 | hvsi_insert_chars(hp, tty, data, datalen); | 378 | hvsi_insert_chars(hp, data, datalen); |
381 | 379 | ||
382 | if (overflow > 0) { | 380 | if (overflow > 0) { |
383 | /* | 381 | /* |
@@ -438,9 +436,7 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty, | |||
438 | case VS_DATA_PACKET_HEADER: | 436 | case VS_DATA_PACKET_HEADER: |
439 | if (!is_open(hp)) | 437 | if (!is_open(hp)) |
440 | break; | 438 | break; |
441 | if (tty == NULL) | 439 | flip = hvsi_recv_data(hp, packet); |
442 | break; /* no tty buffer to put data in */ | ||
443 | flip = hvsi_recv_data(hp, tty, packet); | ||
444 | break; | 440 | break; |
445 | case VS_CONTROL_PACKET_HEADER: | 441 | case VS_CONTROL_PACKET_HEADER: |
446 | hvsi_recv_control(hp, packet, tty, handshake); | 442 | hvsi_recv_control(hp, packet, tty, handshake); |
@@ -469,17 +465,17 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty, | |||
469 | compact_inbuf(hp, packet); | 465 | compact_inbuf(hp, packet); |
470 | 466 | ||
471 | if (flip) | 467 | if (flip) |
472 | tty_flip_buffer_push(tty); | 468 | tty_flip_buffer_push(&hp->port); |
473 | 469 | ||
474 | return 1; | 470 | return 1; |
475 | } | 471 | } |
476 | 472 | ||
477 | static void hvsi_send_overflow(struct hvsi_struct *hp, struct tty_struct *tty) | 473 | static void hvsi_send_overflow(struct hvsi_struct *hp) |
478 | { | 474 | { |
479 | pr_debug("%s: delivering %i bytes overflow\n", __func__, | 475 | pr_debug("%s: delivering %i bytes overflow\n", __func__, |
480 | hp->n_throttle); | 476 | hp->n_throttle); |
481 | 477 | ||
482 | hvsi_insert_chars(hp, tty, hp->throttle_buf, hp->n_throttle); | 478 | hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle); |
483 | hp->n_throttle = 0; | 479 | hp->n_throttle = 0; |
484 | } | 480 | } |
485 | 481 | ||
@@ -514,8 +510,8 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg) | |||
514 | if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) { | 510 | if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) { |
515 | /* we weren't hung up and we weren't throttled, so we can | 511 | /* we weren't hung up and we weren't throttled, so we can |
516 | * deliver the rest now */ | 512 | * deliver the rest now */ |
517 | hvsi_send_overflow(hp, tty); | 513 | hvsi_send_overflow(hp); |
518 | tty_flip_buffer_push(tty); | 514 | tty_flip_buffer_push(&hp->port); |
519 | } | 515 | } |
520 | spin_unlock_irqrestore(&hp->lock, flags); | 516 | spin_unlock_irqrestore(&hp->lock, flags); |
521 | 517 | ||
@@ -1001,8 +997,8 @@ static void hvsi_unthrottle(struct tty_struct *tty) | |||
1001 | 997 | ||
1002 | spin_lock_irqsave(&hp->lock, flags); | 998 | spin_lock_irqsave(&hp->lock, flags); |
1003 | if (hp->n_throttle) { | 999 | if (hp->n_throttle) { |
1004 | hvsi_send_overflow(hp, tty); | 1000 | hvsi_send_overflow(hp); |
1005 | tty_flip_buffer_push(tty); | 1001 | tty_flip_buffer_push(&hp->port); |
1006 | } | 1002 | } |
1007 | spin_unlock_irqrestore(&hp->lock, flags); | 1003 | spin_unlock_irqrestore(&hp->lock, flags); |
1008 | 1004 | ||
@@ -1187,9 +1183,7 @@ static int __init hvsi_console_init(void) | |||
1187 | hvsi_wait = poll_for_state; /* no irqs yet; must poll */ | 1183 | hvsi_wait = poll_for_state; /* no irqs yet; must poll */ |
1188 | 1184 | ||
1189 | /* search device tree for vty nodes */ | 1185 | /* search device tree for vty nodes */ |
1190 | for (vty = of_find_compatible_node(NULL, "serial", "hvterm-protocol"); | 1186 | for_each_compatible_node(vty, "serial", "hvterm-protocol") { |
1191 | vty != NULL; | ||
1192 | vty = of_find_compatible_node(vty, "serial", "hvterm-protocol")) { | ||
1193 | struct hvsi_struct *hp; | 1187 | struct hvsi_struct *hp; |
1194 | const uint32_t *vtermno, *irq; | 1188 | const uint32_t *vtermno, *irq; |
1195 | 1189 | ||
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 2cde13ddf9fc..8fd72ff9436e 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c | |||
@@ -106,7 +106,7 @@ static int ipw_open(struct tty_struct *linux_tty, struct file *filp) | |||
106 | 106 | ||
107 | tty->port.tty = linux_tty; | 107 | tty->port.tty = linux_tty; |
108 | linux_tty->driver_data = tty; | 108 | linux_tty->driver_data = tty; |
109 | linux_tty->low_latency = 1; | 109 | tty->port.low_latency = 1; |
110 | 110 | ||
111 | if (tty->tty_type == TTYTYPE_MODEM) | 111 | if (tty->tty_type == TTYTYPE_MODEM) |
112 | ipwireless_ppp_open(tty->network); | 112 | ipwireless_ppp_open(tty->network); |
@@ -160,15 +160,9 @@ static void ipw_close(struct tty_struct *linux_tty, struct file *filp) | |||
160 | void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, | 160 | void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, |
161 | unsigned int length) | 161 | unsigned int length) |
162 | { | 162 | { |
163 | struct tty_struct *linux_tty; | ||
164 | int work = 0; | 163 | int work = 0; |
165 | 164 | ||
166 | mutex_lock(&tty->ipw_tty_mutex); | 165 | mutex_lock(&tty->ipw_tty_mutex); |
167 | linux_tty = tty->port.tty; | ||
168 | if (linux_tty == NULL) { | ||
169 | mutex_unlock(&tty->ipw_tty_mutex); | ||
170 | return; | ||
171 | } | ||
172 | 166 | ||
173 | if (!tty->port.count) { | 167 | if (!tty->port.count) { |
174 | mutex_unlock(&tty->ipw_tty_mutex); | 168 | mutex_unlock(&tty->ipw_tty_mutex); |
@@ -176,7 +170,7 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, | |||
176 | } | 170 | } |
177 | mutex_unlock(&tty->ipw_tty_mutex); | 171 | mutex_unlock(&tty->ipw_tty_mutex); |
178 | 172 | ||
179 | work = tty_insert_flip_string(linux_tty, data, length); | 173 | work = tty_insert_flip_string(&tty->port, data, length); |
180 | 174 | ||
181 | if (work != length) | 175 | if (work != length) |
182 | printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME | 176 | printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME |
@@ -187,7 +181,7 @@ void ipwireless_tty_received(struct ipw_tty *tty, unsigned char *data, | |||
187 | * This may sleep if ->low_latency is set | 181 | * This may sleep if ->low_latency is set |
188 | */ | 182 | */ |
189 | if (work) | 183 | if (work) |
190 | tty_flip_buffer_push(linux_tty); | 184 | tty_flip_buffer_push(&tty->port); |
191 | } | 185 | } |
192 | 186 | ||
193 | static void ipw_write_packet_sent_callback(void *callback_data, | 187 | static void ipw_write_packet_sent_callback(void *callback_data, |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 3205b2e9090b..858291ca889c 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
@@ -634,10 +634,10 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
634 | break; | 634 | break; |
635 | 635 | ||
636 | case 1: /* Received Break !!! */ | 636 | case 1: /* Received Break !!! */ |
637 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 637 | tty_insert_flip_char(&port->port, 0, TTY_BREAK); |
638 | if (port->port.flags & ASYNC_SAK) | 638 | if (port->port.flags & ASYNC_SAK) |
639 | do_SAK(tty); | 639 | do_SAK(tty); |
640 | tty_flip_buffer_push(tty); | 640 | tty_flip_buffer_push(&port->port); |
641 | break; | 641 | break; |
642 | 642 | ||
643 | case 2: /* Statistics */ | 643 | case 2: /* Statistics */ |
@@ -650,15 +650,15 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
650 | break; | 650 | break; |
651 | } | 651 | } |
652 | } else { /* Data Packet */ | 652 | } else { /* Data Packet */ |
653 | 653 | count = tty_prepare_flip_string(&port->port, &rp, | |
654 | count = tty_prepare_flip_string(tty, &rp, byte_count & ~1); | 654 | byte_count & ~1); |
655 | pr_debug("%s: Can rx %d of %d bytes.\n", | 655 | pr_debug("%s: Can rx %d of %d bytes.\n", |
656 | __func__, count, byte_count); | 656 | __func__, count, byte_count); |
657 | word_count = count >> 1; | 657 | word_count = count >> 1; |
658 | insw(base, rp, word_count); | 658 | insw(base, rp, word_count); |
659 | byte_count -= (word_count << 1); | 659 | byte_count -= (word_count << 1); |
660 | if (count & 0x0001) { | 660 | if (count & 0x0001) { |
661 | tty_insert_flip_char(tty, inw(base) & 0xff, | 661 | tty_insert_flip_char(&port->port, inw(base) & 0xff, |
662 | TTY_NORMAL); | 662 | TTY_NORMAL); |
663 | byte_count -= 2; | 663 | byte_count -= 2; |
664 | } | 664 | } |
@@ -671,7 +671,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
671 | byte_count -= 2; | 671 | byte_count -= 2; |
672 | } | 672 | } |
673 | } | 673 | } |
674 | tty_flip_buffer_push(tty); | 674 | tty_flip_buffer_push(&port->port); |
675 | } | 675 | } |
676 | outw(0x0000, base+0x04); /* enable interrupts */ | 676 | outw(0x0000, base+0x04); /* enable interrupts */ |
677 | spin_unlock(&card->card_lock); | 677 | spin_unlock(&card->card_lock); |
diff --git a/drivers/tty/metag_da.c b/drivers/tty/metag_da.c new file mode 100644 index 000000000000..0e888621f484 --- /dev/null +++ b/drivers/tty/metag_da.c | |||
@@ -0,0 +1,677 @@ | |||
1 | /* | ||
2 | * dashtty.c - tty driver for Dash channels interface. | ||
3 | * | ||
4 | * Copyright (C) 2007,2008,2012 Imagination Technologies | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file COPYING in the main directory of this archive | ||
8 | * for more details. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/atomic.h> | ||
13 | #include <linux/completion.h> | ||
14 | #include <linux/console.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/export.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/kthread.h> | ||
20 | #include <linux/mutex.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/serial.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/string.h> | ||
26 | #include <linux/timer.h> | ||
27 | #include <linux/tty.h> | ||
28 | #include <linux/tty_driver.h> | ||
29 | #include <linux/tty_flip.h> | ||
30 | #include <linux/uaccess.h> | ||
31 | |||
32 | #include <asm/da.h> | ||
33 | |||
34 | /* Channel error codes */ | ||
35 | #define CONAOK 0 | ||
36 | #define CONERR 1 | ||
37 | #define CONBAD 2 | ||
38 | #define CONPRM 3 | ||
39 | #define CONADR 4 | ||
40 | #define CONCNT 5 | ||
41 | #define CONCBF 6 | ||
42 | #define CONCBE 7 | ||
43 | #define CONBSY 8 | ||
44 | |||
45 | /* Default channel for the console */ | ||
46 | #define CONSOLE_CHANNEL 1 | ||
47 | |||
48 | #define NUM_TTY_CHANNELS 6 | ||
49 | |||
50 | /* Auto allocate */ | ||
51 | #define DA_TTY_MAJOR 0 | ||
52 | |||
53 | /* A speedy poll rate helps the userland debug process connection response. | ||
54 | * But, if you set it too high then no other userland processes get much | ||
55 | * of a look in. | ||
56 | */ | ||
57 | #define DA_TTY_POLL (HZ / 50) | ||
58 | |||
59 | /* | ||
60 | * A short put delay improves latency but has a high throughput overhead | ||
61 | */ | ||
62 | #define DA_TTY_PUT_DELAY (HZ / 100) | ||
63 | |||
64 | static atomic_t num_channels_need_poll = ATOMIC_INIT(0); | ||
65 | |||
66 | static struct timer_list poll_timer; | ||
67 | |||
68 | static struct tty_driver *channel_driver; | ||
69 | |||
70 | static struct timer_list put_timer; | ||
71 | static struct task_struct *dashtty_thread; | ||
72 | |||
73 | #define RX_BUF_SIZE 1024 | ||
74 | |||
75 | enum { | ||
76 | INCHR = 1, | ||
77 | OUTCHR, | ||
78 | RDBUF, | ||
79 | WRBUF, | ||
80 | RDSTAT | ||
81 | }; | ||
82 | |||
83 | /** | ||
84 | * struct dashtty_port - Wrapper struct for dashtty tty_port. | ||
85 | * @port: TTY port data | ||
86 | * @rx_lock: Lock for rx_buf. | ||
87 | * This protects between the poll timer and user context. | ||
88 | * It's also held during read SWITCH operations. | ||
89 | * @rx_buf: Read buffer | ||
90 | * @xmit_lock: Lock for xmit_*, and port.xmit_buf. | ||
91 | * This protects between user context and kernel thread. | ||
92 | * It's also held during write SWITCH operations. | ||
93 | * @xmit_cnt: Size of xmit buffer contents | ||
94 | * @xmit_head: Head of xmit buffer where data is written | ||
95 | * @xmit_tail: Tail of xmit buffer where data is read | ||
96 | * @xmit_empty: Completion for xmit buffer being empty | ||
97 | */ | ||
98 | struct dashtty_port { | ||
99 | struct tty_port port; | ||
100 | spinlock_t rx_lock; | ||
101 | void *rx_buf; | ||
102 | struct mutex xmit_lock; | ||
103 | unsigned int xmit_cnt; | ||
104 | unsigned int xmit_head; | ||
105 | unsigned int xmit_tail; | ||
106 | struct completion xmit_empty; | ||
107 | }; | ||
108 | |||
109 | static struct dashtty_port dashtty_ports[NUM_TTY_CHANNELS]; | ||
110 | |||
111 | static atomic_t dashtty_xmit_cnt = ATOMIC_INIT(0); | ||
112 | static wait_queue_head_t dashtty_waitqueue; | ||
113 | |||
114 | /* | ||
115 | * Low-level DA channel access routines | ||
116 | */ | ||
117 | static int chancall(int in_bios_function, int in_channel, | ||
118 | int in_arg2, void *in_arg3, | ||
119 | void *in_arg4) | ||
120 | { | ||
121 | register int bios_function asm("D1Ar1") = in_bios_function; | ||
122 | register int channel asm("D0Ar2") = in_channel; | ||
123 | register int arg2 asm("D1Ar3") = in_arg2; | ||
124 | register void *arg3 asm("D0Ar4") = in_arg3; | ||
125 | register void *arg4 asm("D1Ar5") = in_arg4; | ||
126 | register int bios_call asm("D0Ar6") = 3; | ||
127 | register int result asm("D0Re0"); | ||
128 | |||
129 | asm volatile ( | ||
130 | "MSETL [A0StP++], %6,%4,%2\n\t" | ||
131 | "ADD A0StP, A0StP, #8\n\t" | ||
132 | "SWITCH #0x0C30208\n\t" | ||
133 | "GETD %0, [A0StP+#-8]\n\t" | ||
134 | "SUB A0StP, A0StP, #(4*6)+8\n\t" | ||
135 | : "=d" (result) /* outs */ | ||
136 | : "d" (bios_function), | ||
137 | "d" (channel), | ||
138 | "d" (arg2), | ||
139 | "d" (arg3), | ||
140 | "d" (arg4), | ||
141 | "d" (bios_call) /* ins */ | ||
142 | : "memory"); | ||
143 | |||
144 | return result; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Attempts to fetch count bytes from channel and returns actual count. | ||
149 | */ | ||
150 | static int fetch_data(unsigned int channel) | ||
151 | { | ||
152 | struct dashtty_port *dport = &dashtty_ports[channel]; | ||
153 | int received = 0; | ||
154 | |||
155 | spin_lock_bh(&dport->rx_lock); | ||
156 | /* check the port isn't being shut down */ | ||
157 | if (!dport->rx_buf) | ||
158 | goto unlock; | ||
159 | if (chancall(RDBUF, channel, RX_BUF_SIZE, | ||
160 | (void *)dport->rx_buf, &received) == CONAOK) { | ||
161 | if (received) { | ||
162 | int space; | ||
163 | unsigned char *cbuf; | ||
164 | |||
165 | space = tty_prepare_flip_string(&dport->port, &cbuf, | ||
166 | received); | ||
167 | |||
168 | if (space <= 0) | ||
169 | goto unlock; | ||
170 | |||
171 | memcpy(cbuf, dport->rx_buf, space); | ||
172 | tty_flip_buffer_push(&dport->port); | ||
173 | } | ||
174 | } | ||
175 | unlock: | ||
176 | spin_unlock_bh(&dport->rx_lock); | ||
177 | |||
178 | return received; | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * find_channel_to_poll() - Returns number of the next channel to poll. | ||
183 | * Returns: The number of the next channel to poll, or -1 if none need | ||
184 | * polling. | ||
185 | */ | ||
186 | static int find_channel_to_poll(void) | ||
187 | { | ||
188 | static int last_polled_channel; | ||
189 | int last = last_polled_channel; | ||
190 | int chan; | ||
191 | struct dashtty_port *dport; | ||
192 | |||
193 | for (chan = last + 1; ; ++chan) { | ||
194 | if (chan >= NUM_TTY_CHANNELS) | ||
195 | chan = 0; | ||
196 | |||
197 | dport = &dashtty_ports[chan]; | ||
198 | if (dport->rx_buf) { | ||
199 | last_polled_channel = chan; | ||
200 | return chan; | ||
201 | } | ||
202 | |||
203 | if (chan == last) | ||
204 | break; | ||
205 | } | ||
206 | return -1; | ||
207 | } | ||
208 | |||
209 | /** | ||
210 | * put_channel_data() - Write out a block of channel data. | ||
211 | * @chan: DA channel number. | ||
212 | * | ||
213 | * Write a single block of data out to the debug adapter. If the circular buffer | ||
214 | * is wrapped then only the first block is written. | ||
215 | * | ||
216 | * Returns: 1 if the remote buffer was too full to accept data. | ||
217 | * 0 otherwise. | ||
218 | */ | ||
219 | static int put_channel_data(unsigned int chan) | ||
220 | { | ||
221 | struct dashtty_port *dport; | ||
222 | struct tty_struct *tty; | ||
223 | int number_written; | ||
224 | unsigned int count = 0; | ||
225 | |||
226 | dport = &dashtty_ports[chan]; | ||
227 | mutex_lock(&dport->xmit_lock); | ||
228 | if (dport->xmit_cnt) { | ||
229 | count = min((unsigned int)(SERIAL_XMIT_SIZE - dport->xmit_tail), | ||
230 | dport->xmit_cnt); | ||
231 | chancall(WRBUF, chan, count, | ||
232 | dport->port.xmit_buf + dport->xmit_tail, | ||
233 | &number_written); | ||
234 | dport->xmit_cnt -= number_written; | ||
235 | if (!dport->xmit_cnt) { | ||
236 | /* reset pointers to avoid wraps */ | ||
237 | dport->xmit_head = 0; | ||
238 | dport->xmit_tail = 0; | ||
239 | complete(&dport->xmit_empty); | ||
240 | } else { | ||
241 | dport->xmit_tail += number_written; | ||
242 | if (dport->xmit_tail >= SERIAL_XMIT_SIZE) | ||
243 | dport->xmit_tail -= SERIAL_XMIT_SIZE; | ||
244 | } | ||
245 | atomic_sub(number_written, &dashtty_xmit_cnt); | ||
246 | } | ||
247 | mutex_unlock(&dport->xmit_lock); | ||
248 | |||
249 | /* if we've made more data available, wake up tty */ | ||
250 | if (count && number_written) { | ||
251 | tty = tty_port_tty_get(&dport->port); | ||
252 | if (tty) { | ||
253 | tty_wakeup(tty); | ||
254 | tty_kref_put(tty); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | /* did the write fail? */ | ||
259 | return count && !number_written; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * put_data() - Kernel thread to write out blocks of channel data to DA. | ||
264 | * @arg: Unused. | ||
265 | * | ||
266 | * This kernel thread runs while @dashtty_xmit_cnt != 0, and loops over the | ||
267 | * channels to write out any buffered data. If any of the channels stall due to | ||
268 | * the remote buffer being full, a hold off happens to allow the debugger to | ||
269 | * drain the buffer. | ||
270 | */ | ||
271 | static int put_data(void *arg) | ||
272 | { | ||
273 | unsigned int chan, stall; | ||
274 | |||
275 | __set_current_state(TASK_RUNNING); | ||
276 | while (!kthread_should_stop()) { | ||
277 | /* | ||
278 | * For each channel see if there's anything to transmit in the | ||
279 | * port's xmit_buf. | ||
280 | */ | ||
281 | stall = 0; | ||
282 | for (chan = 0; chan < NUM_TTY_CHANNELS; ++chan) | ||
283 | stall += put_channel_data(chan); | ||
284 | |||
285 | /* | ||
286 | * If some of the buffers are full, hold off for a short while | ||
287 | * to allow them to empty. | ||
288 | */ | ||
289 | if (stall) | ||
290 | msleep(25); | ||
291 | |||
292 | wait_event_interruptible(dashtty_waitqueue, | ||
293 | atomic_read(&dashtty_xmit_cnt)); | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * This gets called every DA_TTY_POLL and polls the channels for data | ||
301 | */ | ||
302 | static void dashtty_timer(unsigned long ignored) | ||
303 | { | ||
304 | int channel; | ||
305 | |||
306 | /* If there are no ports open do nothing and don't poll again. */ | ||
307 | if (!atomic_read(&num_channels_need_poll)) | ||
308 | return; | ||
309 | |||
310 | channel = find_channel_to_poll(); | ||
311 | |||
312 | /* Did we find a channel to poll? */ | ||
313 | if (channel >= 0) | ||
314 | fetch_data(channel); | ||
315 | |||
316 | mod_timer_pinned(&poll_timer, jiffies + DA_TTY_POLL); | ||
317 | } | ||
318 | |||
319 | static void add_poll_timer(struct timer_list *poll_timer) | ||
320 | { | ||
321 | setup_timer(poll_timer, dashtty_timer, 0); | ||
322 | poll_timer->expires = jiffies + DA_TTY_POLL; | ||
323 | |||
324 | /* | ||
325 | * Always attach the timer to the boot CPU. The DA channels are per-CPU | ||
326 | * so all polling should be from a single CPU. | ||
327 | */ | ||
328 | add_timer_on(poll_timer, 0); | ||
329 | } | ||
330 | |||
331 | static int dashtty_port_activate(struct tty_port *port, struct tty_struct *tty) | ||
332 | { | ||
333 | struct dashtty_port *dport = container_of(port, struct dashtty_port, | ||
334 | port); | ||
335 | void *rx_buf; | ||
336 | |||
337 | /* Allocate the buffer we use for writing data */ | ||
338 | if (tty_port_alloc_xmit_buf(port) < 0) | ||
339 | goto err; | ||
340 | |||
341 | /* Allocate the buffer we use for reading data */ | ||
342 | rx_buf = kzalloc(RX_BUF_SIZE, GFP_KERNEL); | ||
343 | if (!rx_buf) | ||
344 | goto err_free_xmit; | ||
345 | |||
346 | spin_lock_bh(&dport->rx_lock); | ||
347 | dport->rx_buf = rx_buf; | ||
348 | spin_unlock_bh(&dport->rx_lock); | ||
349 | |||
350 | /* | ||
351 | * Don't add the poll timer if we're opening a console. This | ||
352 | * avoids the overhead of polling the Dash but means it is not | ||
353 | * possible to have a login on /dev/console. | ||
354 | * | ||
355 | */ | ||
356 | if (dport != &dashtty_ports[CONSOLE_CHANNEL]) | ||
357 | if (atomic_inc_return(&num_channels_need_poll) == 1) | ||
358 | add_poll_timer(&poll_timer); | ||
359 | |||
360 | return 0; | ||
361 | err_free_xmit: | ||
362 | tty_port_free_xmit_buf(port); | ||
363 | err: | ||
364 | return -ENOMEM; | ||
365 | } | ||
366 | |||
367 | static void dashtty_port_shutdown(struct tty_port *port) | ||
368 | { | ||
369 | struct dashtty_port *dport = container_of(port, struct dashtty_port, | ||
370 | port); | ||
371 | void *rx_buf; | ||
372 | unsigned int count; | ||
373 | |||
374 | /* stop reading */ | ||
375 | if (dport != &dashtty_ports[CONSOLE_CHANNEL]) | ||
376 | if (atomic_dec_and_test(&num_channels_need_poll)) | ||
377 | del_timer_sync(&poll_timer); | ||
378 | |||
379 | mutex_lock(&dport->xmit_lock); | ||
380 | count = dport->xmit_cnt; | ||
381 | mutex_unlock(&dport->xmit_lock); | ||
382 | if (count) { | ||
383 | /* | ||
384 | * There's still data to write out, so wake and wait for the | ||
385 | * writer thread to drain the buffer. | ||
386 | */ | ||
387 | del_timer(&put_timer); | ||
388 | wake_up_interruptible(&dashtty_waitqueue); | ||
389 | wait_for_completion(&dport->xmit_empty); | ||
390 | } | ||
391 | |||
392 | /* Null the read buffer (timer could still be running!) */ | ||
393 | spin_lock_bh(&dport->rx_lock); | ||
394 | rx_buf = dport->rx_buf; | ||
395 | dport->rx_buf = NULL; | ||
396 | spin_unlock_bh(&dport->rx_lock); | ||
397 | /* Free the read buffer */ | ||
398 | kfree(rx_buf); | ||
399 | |||
400 | /* Free the write buffer */ | ||
401 | tty_port_free_xmit_buf(port); | ||
402 | } | ||
403 | |||
404 | static const struct tty_port_operations dashtty_port_ops = { | ||
405 | .activate = dashtty_port_activate, | ||
406 | .shutdown = dashtty_port_shutdown, | ||
407 | }; | ||
408 | |||
409 | static int dashtty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
410 | { | ||
411 | return tty_port_install(&dashtty_ports[tty->index].port, driver, tty); | ||
412 | } | ||
413 | |||
414 | static int dashtty_open(struct tty_struct *tty, struct file *filp) | ||
415 | { | ||
416 | return tty_port_open(tty->port, tty, filp); | ||
417 | } | ||
418 | |||
419 | static void dashtty_close(struct tty_struct *tty, struct file *filp) | ||
420 | { | ||
421 | return tty_port_close(tty->port, tty, filp); | ||
422 | } | ||
423 | |||
424 | static void dashtty_hangup(struct tty_struct *tty) | ||
425 | { | ||
426 | int channel; | ||
427 | struct dashtty_port *dport; | ||
428 | |||
429 | channel = tty->index; | ||
430 | dport = &dashtty_ports[channel]; | ||
431 | |||
432 | /* drop any data in the xmit buffer */ | ||
433 | mutex_lock(&dport->xmit_lock); | ||
434 | if (dport->xmit_cnt) { | ||
435 | atomic_sub(dport->xmit_cnt, &dashtty_xmit_cnt); | ||
436 | dport->xmit_cnt = 0; | ||
437 | dport->xmit_head = 0; | ||
438 | dport->xmit_tail = 0; | ||
439 | complete(&dport->xmit_empty); | ||
440 | } | ||
441 | mutex_unlock(&dport->xmit_lock); | ||
442 | |||
443 | tty_port_hangup(tty->port); | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * dashtty_put_timer() - Delayed wake up of kernel thread. | ||
448 | * @ignored: unused | ||
449 | * | ||
450 | * This timer function wakes up the kernel thread if any data exists in the | ||
451 | * buffers. It is used to delay the expensive writeout until the writer has | ||
452 | * stopped writing. | ||
453 | */ | ||
454 | static void dashtty_put_timer(unsigned long ignored) | ||
455 | { | ||
456 | if (atomic_read(&dashtty_xmit_cnt)) | ||
457 | wake_up_interruptible(&dashtty_waitqueue); | ||
458 | } | ||
459 | |||
460 | static int dashtty_write(struct tty_struct *tty, const unsigned char *buf, | ||
461 | int total) | ||
462 | { | ||
463 | int channel, count, block; | ||
464 | struct dashtty_port *dport; | ||
465 | |||
466 | /* Determine the channel */ | ||
467 | channel = tty->index; | ||
468 | dport = &dashtty_ports[channel]; | ||
469 | |||
470 | /* | ||
471 | * Write to output buffer. | ||
472 | * | ||
473 | * The reason that we asynchronously write the buffer is because if we | ||
474 | * were to write the buffer synchronously then because DA channels are | ||
475 | * per-CPU the buffer would be written to the channel of whatever CPU | ||
476 | * we're running on. | ||
477 | * | ||
478 | * What we actually want to happen is have all input and output done on | ||
479 | * one CPU. | ||
480 | */ | ||
481 | mutex_lock(&dport->xmit_lock); | ||
482 | /* work out how many bytes we can write to the xmit buffer */ | ||
483 | total = min(total, (int)(SERIAL_XMIT_SIZE - dport->xmit_cnt)); | ||
484 | atomic_add(total, &dashtty_xmit_cnt); | ||
485 | dport->xmit_cnt += total; | ||
486 | /* write the actual bytes (may need splitting if it wraps) */ | ||
487 | for (count = total; count; count -= block) { | ||
488 | block = min(count, (int)(SERIAL_XMIT_SIZE - dport->xmit_head)); | ||
489 | memcpy(dport->port.xmit_buf + dport->xmit_head, buf, block); | ||
490 | dport->xmit_head += block; | ||
491 | if (dport->xmit_head >= SERIAL_XMIT_SIZE) | ||
492 | dport->xmit_head -= SERIAL_XMIT_SIZE; | ||
493 | buf += block; | ||
494 | } | ||
495 | count = dport->xmit_cnt; | ||
496 | /* xmit buffer no longer empty? */ | ||
497 | if (count) | ||
498 | INIT_COMPLETION(dport->xmit_empty); | ||
499 | mutex_unlock(&dport->xmit_lock); | ||
500 | |||
501 | if (total) { | ||
502 | /* | ||
503 | * If the buffer is full, wake up the kthread, otherwise allow | ||
504 | * some more time for the buffer to fill up a bit before waking | ||
505 | * it. | ||
506 | */ | ||
507 | if (count == SERIAL_XMIT_SIZE) { | ||
508 | del_timer(&put_timer); | ||
509 | wake_up_interruptible(&dashtty_waitqueue); | ||
510 | } else { | ||
511 | mod_timer(&put_timer, jiffies + DA_TTY_PUT_DELAY); | ||
512 | } | ||
513 | } | ||
514 | return total; | ||
515 | } | ||
516 | |||
517 | static int dashtty_write_room(struct tty_struct *tty) | ||
518 | { | ||
519 | struct dashtty_port *dport; | ||
520 | int channel; | ||
521 | int room; | ||
522 | |||
523 | channel = tty->index; | ||
524 | dport = &dashtty_ports[channel]; | ||
525 | |||
526 | /* report the space in the xmit buffer */ | ||
527 | mutex_lock(&dport->xmit_lock); | ||
528 | room = SERIAL_XMIT_SIZE - dport->xmit_cnt; | ||
529 | mutex_unlock(&dport->xmit_lock); | ||
530 | |||
531 | return room; | ||
532 | } | ||
533 | |||
534 | static int dashtty_chars_in_buffer(struct tty_struct *tty) | ||
535 | { | ||
536 | struct dashtty_port *dport; | ||
537 | int channel; | ||
538 | int chars; | ||
539 | |||
540 | channel = tty->index; | ||
541 | dport = &dashtty_ports[channel]; | ||
542 | |||
543 | /* report the number of bytes in the xmit buffer */ | ||
544 | mutex_lock(&dport->xmit_lock); | ||
545 | chars = dport->xmit_cnt; | ||
546 | mutex_unlock(&dport->xmit_lock); | ||
547 | |||
548 | return chars; | ||
549 | } | ||
550 | |||
551 | static const struct tty_operations dashtty_ops = { | ||
552 | .install = dashtty_install, | ||
553 | .open = dashtty_open, | ||
554 | .close = dashtty_close, | ||
555 | .hangup = dashtty_hangup, | ||
556 | .write = dashtty_write, | ||
557 | .write_room = dashtty_write_room, | ||
558 | .chars_in_buffer = dashtty_chars_in_buffer, | ||
559 | }; | ||
560 | |||
561 | static int __init dashtty_init(void) | ||
562 | { | ||
563 | int ret; | ||
564 | int nport; | ||
565 | struct dashtty_port *dport; | ||
566 | |||
567 | if (!metag_da_enabled()) | ||
568 | return -ENODEV; | ||
569 | |||
570 | channel_driver = tty_alloc_driver(NUM_TTY_CHANNELS, | ||
571 | TTY_DRIVER_REAL_RAW); | ||
572 | if (IS_ERR(channel_driver)) | ||
573 | return PTR_ERR(channel_driver); | ||
574 | |||
575 | channel_driver->driver_name = "metag_da"; | ||
576 | channel_driver->name = "ttyDA"; | ||
577 | channel_driver->major = DA_TTY_MAJOR; | ||
578 | channel_driver->minor_start = 0; | ||
579 | channel_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
580 | channel_driver->subtype = SERIAL_TYPE_NORMAL; | ||
581 | channel_driver->init_termios = tty_std_termios; | ||
582 | channel_driver->init_termios.c_cflag |= CLOCAL; | ||
583 | |||
584 | tty_set_operations(channel_driver, &dashtty_ops); | ||
585 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
586 | dport = &dashtty_ports[nport]; | ||
587 | tty_port_init(&dport->port); | ||
588 | dport->port.ops = &dashtty_port_ops; | ||
589 | spin_lock_init(&dport->rx_lock); | ||
590 | mutex_init(&dport->xmit_lock); | ||
591 | /* the xmit buffer starts empty, i.e. completely written */ | ||
592 | init_completion(&dport->xmit_empty); | ||
593 | complete(&dport->xmit_empty); | ||
594 | } | ||
595 | |||
596 | setup_timer(&put_timer, dashtty_put_timer, 0); | ||
597 | |||
598 | init_waitqueue_head(&dashtty_waitqueue); | ||
599 | dashtty_thread = kthread_create(put_data, NULL, "ttyDA"); | ||
600 | if (IS_ERR(dashtty_thread)) { | ||
601 | pr_err("Couldn't create dashtty thread\n"); | ||
602 | ret = PTR_ERR(dashtty_thread); | ||
603 | goto err_destroy_ports; | ||
604 | } | ||
605 | /* | ||
606 | * Bind the writer thread to the boot CPU so it can't migrate. | ||
607 | * DA channels are per-CPU and we want all channel I/O to be on a single | ||
608 | * predictable CPU. | ||
609 | */ | ||
610 | kthread_bind(dashtty_thread, 0); | ||
611 | wake_up_process(dashtty_thread); | ||
612 | |||
613 | ret = tty_register_driver(channel_driver); | ||
614 | |||
615 | if (ret < 0) { | ||
616 | pr_err("Couldn't install dashtty driver: err %d\n", | ||
617 | ret); | ||
618 | goto err_stop_kthread; | ||
619 | } | ||
620 | |||
621 | return 0; | ||
622 | |||
623 | err_stop_kthread: | ||
624 | kthread_stop(dashtty_thread); | ||
625 | err_destroy_ports: | ||
626 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
627 | dport = &dashtty_ports[nport]; | ||
628 | tty_port_destroy(&dport->port); | ||
629 | } | ||
630 | put_tty_driver(channel_driver); | ||
631 | return ret; | ||
632 | } | ||
633 | |||
634 | static void dashtty_exit(void) | ||
635 | { | ||
636 | int nport; | ||
637 | struct dashtty_port *dport; | ||
638 | |||
639 | del_timer_sync(&put_timer); | ||
640 | kthread_stop(dashtty_thread); | ||
641 | del_timer_sync(&poll_timer); | ||
642 | tty_unregister_driver(channel_driver); | ||
643 | for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { | ||
644 | dport = &dashtty_ports[nport]; | ||
645 | tty_port_destroy(&dport->port); | ||
646 | } | ||
647 | put_tty_driver(channel_driver); | ||
648 | } | ||
649 | |||
650 | module_init(dashtty_init); | ||
651 | module_exit(dashtty_exit); | ||
652 | |||
653 | #ifdef CONFIG_DA_CONSOLE | ||
654 | |||
655 | static void dash_console_write(struct console *co, const char *s, | ||
656 | unsigned int count) | ||
657 | { | ||
658 | int actually_written; | ||
659 | |||
660 | chancall(WRBUF, CONSOLE_CHANNEL, count, (void *)s, &actually_written); | ||
661 | } | ||
662 | |||
663 | static struct tty_driver *dash_console_device(struct console *c, int *index) | ||
664 | { | ||
665 | *index = c->index; | ||
666 | return channel_driver; | ||
667 | } | ||
668 | |||
669 | struct console dash_console = { | ||
670 | .name = "ttyDA", | ||
671 | .write = dash_console_write, | ||
672 | .device = dash_console_device, | ||
673 | .flags = CON_PRINTBUFFER, | ||
674 | .index = 1, | ||
675 | }; | ||
676 | |||
677 | #endif | ||
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index f9d28503bdec..adeac255e526 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
@@ -1405,7 +1405,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1405 | if (inited && !test_bit(TTY_THROTTLED, &tty->flags) && | 1405 | if (inited && !test_bit(TTY_THROTTLED, &tty->flags) && |
1406 | MoxaPortRxQueue(p) > 0) { /* RX */ | 1406 | MoxaPortRxQueue(p) > 0) { /* RX */ |
1407 | MoxaPortReadData(p); | 1407 | MoxaPortReadData(p); |
1408 | tty_schedule_flip(tty); | 1408 | tty_schedule_flip(&p->port); |
1409 | } | 1409 | } |
1410 | } else { | 1410 | } else { |
1411 | clear_bit(EMPTYWAIT, &p->statusflags); | 1411 | clear_bit(EMPTYWAIT, &p->statusflags); |
@@ -1429,8 +1429,8 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, | |||
1429 | goto put; | 1429 | goto put; |
1430 | 1430 | ||
1431 | if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ | 1431 | if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ |
1432 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1432 | tty_insert_flip_char(&p->port, 0, TTY_BREAK); |
1433 | tty_schedule_flip(tty); | 1433 | tty_schedule_flip(&p->port); |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | if (intr & IntrLine) | 1436 | if (intr & IntrLine) |
@@ -1966,7 +1966,7 @@ static int MoxaPortReadData(struct moxa_port *port) | |||
1966 | ofs = baseAddr + DynPage_addr + bufhead + head; | 1966 | ofs = baseAddr + DynPage_addr + bufhead + head; |
1967 | len = (tail >= head) ? (tail - head) : | 1967 | len = (tail >= head) ? (tail - head) : |
1968 | (rx_mask + 1 - head); | 1968 | (rx_mask + 1 - head); |
1969 | len = tty_prepare_flip_string(tty, &dst, | 1969 | len = tty_prepare_flip_string(&port->port, &dst, |
1970 | min(len, count)); | 1970 | min(len, count)); |
1971 | memcpy_fromio(dst, ofs, len); | 1971 | memcpy_fromio(dst, ofs, len); |
1972 | head = (head + len) & rx_mask; | 1972 | head = (head + len) & rx_mask; |
@@ -1978,7 +1978,7 @@ static int MoxaPortReadData(struct moxa_port *port) | |||
1978 | while (count > 0) { | 1978 | while (count > 0) { |
1979 | writew(pageno, baseAddr + Control_reg); | 1979 | writew(pageno, baseAddr + Control_reg); |
1980 | ofs = baseAddr + DynPage_addr + pageofs; | 1980 | ofs = baseAddr + DynPage_addr + pageofs; |
1981 | len = tty_prepare_flip_string(tty, &dst, | 1981 | len = tty_prepare_flip_string(&port->port, &dst, |
1982 | min(Page_size - pageofs, count)); | 1982 | min(Page_size - pageofs, count)); |
1983 | memcpy_fromio(dst, ofs, len); | 1983 | memcpy_fromio(dst, ofs, len); |
1984 | 1984 | ||
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 40113868bec2..484b6a3c9b03 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -1264,7 +1264,7 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1264 | (new_serial.flags & ASYNC_FLAGS)); | 1264 | (new_serial.flags & ASYNC_FLAGS)); |
1265 | port->close_delay = new_serial.close_delay * HZ / 100; | 1265 | port->close_delay = new_serial.close_delay * HZ / 100; |
1266 | port->closing_wait = new_serial.closing_wait * HZ / 100; | 1266 | port->closing_wait = new_serial.closing_wait * HZ / 100; |
1267 | tty->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 1267 | port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
1268 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && | 1268 | if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && |
1269 | (new_serial.baud_base != info->baud_base || | 1269 | (new_serial.baud_base != info->baud_base || |
1270 | new_serial.custom_divisor != | 1270 | new_serial.custom_divisor != |
@@ -2079,7 +2079,7 @@ static void mxser_receive_chars(struct tty_struct *tty, | |||
2079 | } | 2079 | } |
2080 | while (gdl--) { | 2080 | while (gdl--) { |
2081 | ch = inb(port->ioaddr + UART_RX); | 2081 | ch = inb(port->ioaddr + UART_RX); |
2082 | tty_insert_flip_char(tty, ch, 0); | 2082 | tty_insert_flip_char(&port->port, ch, 0); |
2083 | cnt++; | 2083 | cnt++; |
2084 | } | 2084 | } |
2085 | goto end_intr; | 2085 | goto end_intr; |
@@ -2118,7 +2118,7 @@ intr_old: | |||
2118 | } else | 2118 | } else |
2119 | flag = TTY_BREAK; | 2119 | flag = TTY_BREAK; |
2120 | } | 2120 | } |
2121 | tty_insert_flip_char(tty, ch, flag); | 2121 | tty_insert_flip_char(&port->port, ch, flag); |
2122 | cnt++; | 2122 | cnt++; |
2123 | if (cnt >= recv_room) { | 2123 | if (cnt >= recv_room) { |
2124 | if (!port->ldisc_stop_rx) | 2124 | if (!port->ldisc_stop_rx) |
@@ -2145,7 +2145,7 @@ end_intr: | |||
2145 | * recursive locking. | 2145 | * recursive locking. |
2146 | */ | 2146 | */ |
2147 | spin_unlock(&port->slock); | 2147 | spin_unlock(&port->slock); |
2148 | tty_flip_buffer_push(tty); | 2148 | tty_flip_buffer_push(&port->port); |
2149 | spin_lock(&port->slock); | 2149 | spin_lock(&port->slock); |
2150 | } | 2150 | } |
2151 | 2151 | ||
@@ -2364,7 +2364,6 @@ static void mxser_release_vector(struct mxser_board *brd) | |||
2364 | 2364 | ||
2365 | static void mxser_release_ISA_res(struct mxser_board *brd) | 2365 | static void mxser_release_ISA_res(struct mxser_board *brd) |
2366 | { | 2366 | { |
2367 | free_irq(brd->irq, brd); | ||
2368 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | 2367 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); |
2369 | mxser_release_vector(brd); | 2368 | mxser_release_vector(brd); |
2370 | } | 2369 | } |
@@ -2430,6 +2429,7 @@ static void mxser_board_remove(struct mxser_board *brd) | |||
2430 | tty_unregister_device(mxvar_sdriver, brd->idx + i); | 2429 | tty_unregister_device(mxvar_sdriver, brd->idx + i); |
2431 | tty_port_destroy(&brd->ports[i].port); | 2430 | tty_port_destroy(&brd->ports[i].port); |
2432 | } | 2431 | } |
2432 | free_irq(brd->irq, brd); | ||
2433 | } | 2433 | } |
2434 | 2434 | ||
2435 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | 2435 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) |
@@ -2554,6 +2554,7 @@ static int mxser_probe(struct pci_dev *pdev, | |||
2554 | struct mxser_board *brd; | 2554 | struct mxser_board *brd; |
2555 | unsigned int i, j; | 2555 | unsigned int i, j; |
2556 | unsigned long ioaddress; | 2556 | unsigned long ioaddress; |
2557 | struct device *tty_dev; | ||
2557 | int retval = -EINVAL; | 2558 | int retval = -EINVAL; |
2558 | 2559 | ||
2559 | for (i = 0; i < MXSER_BOARDS; i++) | 2560 | for (i = 0; i < MXSER_BOARDS; i++) |
@@ -2637,13 +2638,25 @@ static int mxser_probe(struct pci_dev *pdev, | |||
2637 | if (retval) | 2638 | if (retval) |
2638 | goto err_rel3; | 2639 | goto err_rel3; |
2639 | 2640 | ||
2640 | for (i = 0; i < brd->info->nports; i++) | 2641 | for (i = 0; i < brd->info->nports; i++) { |
2641 | tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, | 2642 | tty_dev = tty_port_register_device(&brd->ports[i].port, |
2642 | brd->idx + i, &pdev->dev); | 2643 | mxvar_sdriver, brd->idx + i, &pdev->dev); |
2644 | if (IS_ERR(tty_dev)) { | ||
2645 | retval = PTR_ERR(tty_dev); | ||
2646 | for (i--; i >= 0; i--) | ||
2647 | tty_unregister_device(mxvar_sdriver, | ||
2648 | brd->idx + i); | ||
2649 | goto err_relbrd; | ||
2650 | } | ||
2651 | } | ||
2643 | 2652 | ||
2644 | pci_set_drvdata(pdev, brd); | 2653 | pci_set_drvdata(pdev, brd); |
2645 | 2654 | ||
2646 | return 0; | 2655 | return 0; |
2656 | err_relbrd: | ||
2657 | for (i = 0; i < brd->info->nports; i++) | ||
2658 | tty_port_destroy(&brd->ports[i].port); | ||
2659 | free_irq(brd->irq, brd); | ||
2647 | err_rel3: | 2660 | err_rel3: |
2648 | pci_release_region(pdev, 3); | 2661 | pci_release_region(pdev, 3); |
2649 | err_zero: | 2662 | err_zero: |
@@ -2665,7 +2678,6 @@ static void mxser_remove(struct pci_dev *pdev) | |||
2665 | 2678 | ||
2666 | mxser_board_remove(brd); | 2679 | mxser_board_remove(brd); |
2667 | 2680 | ||
2668 | free_irq(pdev->irq, brd); | ||
2669 | pci_release_region(pdev, 2); | 2681 | pci_release_region(pdev, 2); |
2670 | pci_release_region(pdev, 3); | 2682 | pci_release_region(pdev, 3); |
2671 | pci_disable_device(pdev); | 2683 | pci_disable_device(pdev); |
@@ -2683,6 +2695,7 @@ static struct pci_driver mxser_driver = { | |||
2683 | static int __init mxser_module_init(void) | 2695 | static int __init mxser_module_init(void) |
2684 | { | 2696 | { |
2685 | struct mxser_board *brd; | 2697 | struct mxser_board *brd; |
2698 | struct device *tty_dev; | ||
2686 | unsigned int b, i, m; | 2699 | unsigned int b, i, m; |
2687 | int retval; | 2700 | int retval; |
2688 | 2701 | ||
@@ -2728,14 +2741,29 @@ static int __init mxser_module_init(void) | |||
2728 | 2741 | ||
2729 | /* mxser_initbrd will hook ISR. */ | 2742 | /* mxser_initbrd will hook ISR. */ |
2730 | if (mxser_initbrd(brd, NULL) < 0) { | 2743 | if (mxser_initbrd(brd, NULL) < 0) { |
2744 | mxser_release_ISA_res(brd); | ||
2731 | brd->info = NULL; | 2745 | brd->info = NULL; |
2732 | continue; | 2746 | continue; |
2733 | } | 2747 | } |
2734 | 2748 | ||
2735 | brd->idx = m * MXSER_PORTS_PER_BOARD; | 2749 | brd->idx = m * MXSER_PORTS_PER_BOARD; |
2736 | for (i = 0; i < brd->info->nports; i++) | 2750 | for (i = 0; i < brd->info->nports; i++) { |
2737 | tty_port_register_device(&brd->ports[i].port, | 2751 | tty_dev = tty_port_register_device(&brd->ports[i].port, |
2738 | mxvar_sdriver, brd->idx + i, NULL); | 2752 | mxvar_sdriver, brd->idx + i, NULL); |
2753 | if (IS_ERR(tty_dev)) { | ||
2754 | for (i--; i >= 0; i--) | ||
2755 | tty_unregister_device(mxvar_sdriver, | ||
2756 | brd->idx + i); | ||
2757 | for (i = 0; i < brd->info->nports; i++) | ||
2758 | tty_port_destroy(&brd->ports[i].port); | ||
2759 | free_irq(brd->irq, brd); | ||
2760 | mxser_release_ISA_res(brd); | ||
2761 | brd->info = NULL; | ||
2762 | break; | ||
2763 | } | ||
2764 | } | ||
2765 | if (brd->info == NULL) | ||
2766 | continue; | ||
2739 | 2767 | ||
2740 | m++; | 2768 | m++; |
2741 | } | 2769 | } |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index dcc0430a49c8..4a43ef5d7962 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -1067,9 +1067,9 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1067 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) | 1067 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) |
1068 | if (!(tty->termios.c_cflag & CLOCAL)) | 1068 | if (!(tty->termios.c_cflag & CLOCAL)) |
1069 | tty_hangup(tty); | 1069 | tty_hangup(tty); |
1070 | if (brk & 0x01) | ||
1071 | tty_insert_flip_char(tty, 0, TTY_BREAK); | ||
1072 | } | 1070 | } |
1071 | if (brk & 0x01) | ||
1072 | tty_insert_flip_char(&dlci->port, 0, TTY_BREAK); | ||
1073 | dlci->modem_rx = mlines; | 1073 | dlci->modem_rx = mlines; |
1074 | } | 1074 | } |
1075 | 1075 | ||
@@ -1137,7 +1137,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen) | |||
1137 | 1137 | ||
1138 | static void gsm_control_rls(struct gsm_mux *gsm, u8 *data, int clen) | 1138 | static void gsm_control_rls(struct gsm_mux *gsm, u8 *data, int clen) |
1139 | { | 1139 | { |
1140 | struct tty_struct *tty; | 1140 | struct tty_port *port; |
1141 | unsigned int addr = 0 ; | 1141 | unsigned int addr = 0 ; |
1142 | u8 bits; | 1142 | u8 bits; |
1143 | int len = clen; | 1143 | int len = clen; |
@@ -1160,19 +1160,18 @@ static void gsm_control_rls(struct gsm_mux *gsm, u8 *data, int clen) | |||
1160 | bits = *dp; | 1160 | bits = *dp; |
1161 | if ((bits & 1) == 0) | 1161 | if ((bits & 1) == 0) |
1162 | return; | 1162 | return; |
1163 | /* See if we have an uplink tty */ | ||
1164 | tty = tty_port_tty_get(&gsm->dlci[addr]->port); | ||
1165 | 1163 | ||
1166 | if (tty) { | 1164 | port = &gsm->dlci[addr]->port; |
1167 | if (bits & 2) | 1165 | |
1168 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1166 | if (bits & 2) |
1169 | if (bits & 4) | 1167 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
1170 | tty_insert_flip_char(tty, 0, TTY_PARITY); | 1168 | if (bits & 4) |
1171 | if (bits & 8) | 1169 | tty_insert_flip_char(port, 0, TTY_PARITY); |
1172 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 1170 | if (bits & 8) |
1173 | tty_flip_buffer_push(tty); | 1171 | tty_insert_flip_char(port, 0, TTY_FRAME); |
1174 | tty_kref_put(tty); | 1172 | |
1175 | } | 1173 | tty_flip_buffer_push(port); |
1174 | |||
1176 | gsm_control_reply(gsm, CMD_RLS, data, clen); | 1175 | gsm_control_reply(gsm, CMD_RLS, data, clen); |
1177 | } | 1176 | } |
1178 | 1177 | ||
@@ -1545,36 +1544,37 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int clen) | |||
1545 | { | 1544 | { |
1546 | /* krefs .. */ | 1545 | /* krefs .. */ |
1547 | struct tty_port *port = &dlci->port; | 1546 | struct tty_port *port = &dlci->port; |
1548 | struct tty_struct *tty = tty_port_tty_get(port); | 1547 | struct tty_struct *tty; |
1549 | unsigned int modem = 0; | 1548 | unsigned int modem = 0; |
1550 | int len = clen; | 1549 | int len = clen; |
1551 | 1550 | ||
1552 | if (debug & 16) | 1551 | if (debug & 16) |
1553 | pr_debug("%d bytes for tty %p\n", len, tty); | 1552 | pr_debug("%d bytes for tty\n", len); |
1554 | if (tty) { | 1553 | switch (dlci->adaption) { |
1555 | switch (dlci->adaption) { | 1554 | /* Unsupported types */ |
1556 | /* Unsupported types */ | 1555 | /* Packetised interruptible data */ |
1557 | /* Packetised interruptible data */ | 1556 | case 4: |
1558 | case 4: | 1557 | break; |
1559 | break; | 1558 | /* Packetised uininterruptible voice/data */ |
1560 | /* Packetised uininterruptible voice/data */ | 1559 | case 3: |
1561 | case 3: | 1560 | break; |
1562 | break; | 1561 | /* Asynchronous serial with line state in each frame */ |
1563 | /* Asynchronous serial with line state in each frame */ | 1562 | case 2: |
1564 | case 2: | 1563 | while (gsm_read_ea(&modem, *data++) == 0) { |
1565 | while (gsm_read_ea(&modem, *data++) == 0) { | 1564 | len--; |
1566 | len--; | 1565 | if (len == 0) |
1567 | if (len == 0) | 1566 | return; |
1568 | return; | 1567 | } |
1569 | } | 1568 | tty = tty_port_tty_get(port); |
1569 | if (tty) { | ||
1570 | gsm_process_modem(tty, dlci, modem, clen); | 1570 | gsm_process_modem(tty, dlci, modem, clen); |
1571 | /* Line state will go via DLCI 0 controls only */ | 1571 | tty_kref_put(tty); |
1572 | case 1: | ||
1573 | default: | ||
1574 | tty_insert_flip_string(tty, data, len); | ||
1575 | tty_flip_buffer_push(tty); | ||
1576 | } | 1572 | } |
1577 | tty_kref_put(tty); | 1573 | /* Line state will go via DLCI 0 controls only */ |
1574 | case 1: | ||
1575 | default: | ||
1576 | tty_insert_flip_string(port, data, len); | ||
1577 | tty_flip_buffer_push(port); | ||
1578 | } | 1578 | } |
1579 | } | 1579 | } |
1580 | 1580 | ||
@@ -1689,6 +1689,8 @@ static inline void dlci_put(struct gsm_dlci *dlci) | |||
1689 | tty_port_put(&dlci->port); | 1689 | tty_port_put(&dlci->port); |
1690 | } | 1690 | } |
1691 | 1691 | ||
1692 | static void gsm_destroy_network(struct gsm_dlci *dlci); | ||
1693 | |||
1692 | /** | 1694 | /** |
1693 | * gsm_dlci_release - release DLCI | 1695 | * gsm_dlci_release - release DLCI |
1694 | * @dlci: DLCI to destroy | 1696 | * @dlci: DLCI to destroy |
@@ -1702,9 +1704,19 @@ static void gsm_dlci_release(struct gsm_dlci *dlci) | |||
1702 | { | 1704 | { |
1703 | struct tty_struct *tty = tty_port_tty_get(&dlci->port); | 1705 | struct tty_struct *tty = tty_port_tty_get(&dlci->port); |
1704 | if (tty) { | 1706 | if (tty) { |
1707 | mutex_lock(&dlci->mutex); | ||
1708 | gsm_destroy_network(dlci); | ||
1709 | mutex_unlock(&dlci->mutex); | ||
1710 | |||
1711 | /* tty_vhangup needs the tty_lock, so unlock and | ||
1712 | relock after doing the hangup. */ | ||
1713 | tty_unlock(tty); | ||
1705 | tty_vhangup(tty); | 1714 | tty_vhangup(tty); |
1715 | tty_lock(tty); | ||
1716 | tty_port_tty_set(&dlci->port, NULL); | ||
1706 | tty_kref_put(tty); | 1717 | tty_kref_put(tty); |
1707 | } | 1718 | } |
1719 | dlci->state = DLCI_CLOSED; | ||
1708 | dlci_put(dlci); | 1720 | dlci_put(dlci); |
1709 | } | 1721 | } |
1710 | 1722 | ||
@@ -2947,6 +2959,8 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp) | |||
2947 | 2959 | ||
2948 | if (dlci == NULL) | 2960 | if (dlci == NULL) |
2949 | return; | 2961 | return; |
2962 | if (dlci->state == DLCI_CLOSED) | ||
2963 | return; | ||
2950 | mutex_lock(&dlci->mutex); | 2964 | mutex_lock(&dlci->mutex); |
2951 | gsm_destroy_network(dlci); | 2965 | gsm_destroy_network(dlci); |
2952 | mutex_unlock(&dlci->mutex); | 2966 | mutex_unlock(&dlci->mutex); |
@@ -2965,6 +2979,8 @@ out: | |||
2965 | static void gsmtty_hangup(struct tty_struct *tty) | 2979 | static void gsmtty_hangup(struct tty_struct *tty) |
2966 | { | 2980 | { |
2967 | struct gsm_dlci *dlci = tty->driver_data; | 2981 | struct gsm_dlci *dlci = tty->driver_data; |
2982 | if (dlci->state == DLCI_CLOSED) | ||
2983 | return; | ||
2968 | tty_port_hangup(&dlci->port); | 2984 | tty_port_hangup(&dlci->port); |
2969 | gsm_dlci_begin_close(dlci); | 2985 | gsm_dlci_begin_close(dlci); |
2970 | } | 2986 | } |
@@ -2972,9 +2988,12 @@ static void gsmtty_hangup(struct tty_struct *tty) | |||
2972 | static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf, | 2988 | static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf, |
2973 | int len) | 2989 | int len) |
2974 | { | 2990 | { |
2991 | int sent; | ||
2975 | struct gsm_dlci *dlci = tty->driver_data; | 2992 | struct gsm_dlci *dlci = tty->driver_data; |
2993 | if (dlci->state == DLCI_CLOSED) | ||
2994 | return -EINVAL; | ||
2976 | /* Stuff the bytes into the fifo queue */ | 2995 | /* Stuff the bytes into the fifo queue */ |
2977 | int sent = kfifo_in_locked(dlci->fifo, buf, len, &dlci->lock); | 2996 | sent = kfifo_in_locked(dlci->fifo, buf, len, &dlci->lock); |
2978 | /* Need to kick the channel */ | 2997 | /* Need to kick the channel */ |
2979 | gsm_dlci_data_kick(dlci); | 2998 | gsm_dlci_data_kick(dlci); |
2980 | return sent; | 2999 | return sent; |
@@ -2983,18 +3002,24 @@ static int gsmtty_write(struct tty_struct *tty, const unsigned char *buf, | |||
2983 | static int gsmtty_write_room(struct tty_struct *tty) | 3002 | static int gsmtty_write_room(struct tty_struct *tty) |
2984 | { | 3003 | { |
2985 | struct gsm_dlci *dlci = tty->driver_data; | 3004 | struct gsm_dlci *dlci = tty->driver_data; |
3005 | if (dlci->state == DLCI_CLOSED) | ||
3006 | return -EINVAL; | ||
2986 | return TX_SIZE - kfifo_len(dlci->fifo); | 3007 | return TX_SIZE - kfifo_len(dlci->fifo); |
2987 | } | 3008 | } |
2988 | 3009 | ||
2989 | static int gsmtty_chars_in_buffer(struct tty_struct *tty) | 3010 | static int gsmtty_chars_in_buffer(struct tty_struct *tty) |
2990 | { | 3011 | { |
2991 | struct gsm_dlci *dlci = tty->driver_data; | 3012 | struct gsm_dlci *dlci = tty->driver_data; |
3013 | if (dlci->state == DLCI_CLOSED) | ||
3014 | return -EINVAL; | ||
2992 | return kfifo_len(dlci->fifo); | 3015 | return kfifo_len(dlci->fifo); |
2993 | } | 3016 | } |
2994 | 3017 | ||
2995 | static void gsmtty_flush_buffer(struct tty_struct *tty) | 3018 | static void gsmtty_flush_buffer(struct tty_struct *tty) |
2996 | { | 3019 | { |
2997 | struct gsm_dlci *dlci = tty->driver_data; | 3020 | struct gsm_dlci *dlci = tty->driver_data; |
3021 | if (dlci->state == DLCI_CLOSED) | ||
3022 | return; | ||
2998 | /* Caution needed: If we implement reliable transport classes | 3023 | /* Caution needed: If we implement reliable transport classes |
2999 | then the data being transmitted can't simply be junked once | 3024 | then the data being transmitted can't simply be junked once |
3000 | it has first hit the stack. Until then we can just blow it | 3025 | it has first hit the stack. Until then we can just blow it |
@@ -3013,6 +3038,8 @@ static void gsmtty_wait_until_sent(struct tty_struct *tty, int timeout) | |||
3013 | static int gsmtty_tiocmget(struct tty_struct *tty) | 3038 | static int gsmtty_tiocmget(struct tty_struct *tty) |
3014 | { | 3039 | { |
3015 | struct gsm_dlci *dlci = tty->driver_data; | 3040 | struct gsm_dlci *dlci = tty->driver_data; |
3041 | if (dlci->state == DLCI_CLOSED) | ||
3042 | return -EINVAL; | ||
3016 | return dlci->modem_rx; | 3043 | return dlci->modem_rx; |
3017 | } | 3044 | } |
3018 | 3045 | ||
@@ -3022,6 +3049,8 @@ static int gsmtty_tiocmset(struct tty_struct *tty, | |||
3022 | struct gsm_dlci *dlci = tty->driver_data; | 3049 | struct gsm_dlci *dlci = tty->driver_data; |
3023 | unsigned int modem_tx = dlci->modem_tx; | 3050 | unsigned int modem_tx = dlci->modem_tx; |
3024 | 3051 | ||
3052 | if (dlci->state == DLCI_CLOSED) | ||
3053 | return -EINVAL; | ||
3025 | modem_tx &= ~clear; | 3054 | modem_tx &= ~clear; |
3026 | modem_tx |= set; | 3055 | modem_tx |= set; |
3027 | 3056 | ||
@@ -3040,6 +3069,8 @@ static int gsmtty_ioctl(struct tty_struct *tty, | |||
3040 | struct gsm_netconfig nc; | 3069 | struct gsm_netconfig nc; |
3041 | int index; | 3070 | int index; |
3042 | 3071 | ||
3072 | if (dlci->state == DLCI_CLOSED) | ||
3073 | return -EINVAL; | ||
3043 | switch (cmd) { | 3074 | switch (cmd) { |
3044 | case GSMIOC_ENABLE_NET: | 3075 | case GSMIOC_ENABLE_NET: |
3045 | if (copy_from_user(&nc, (void __user *)arg, sizeof(nc))) | 3076 | if (copy_from_user(&nc, (void __user *)arg, sizeof(nc))) |
@@ -3066,6 +3097,9 @@ static int gsmtty_ioctl(struct tty_struct *tty, | |||
3066 | 3097 | ||
3067 | static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) | 3098 | static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) |
3068 | { | 3099 | { |
3100 | struct gsm_dlci *dlci = tty->driver_data; | ||
3101 | if (dlci->state == DLCI_CLOSED) | ||
3102 | return; | ||
3069 | /* For the moment its fixed. In actual fact the speed information | 3103 | /* For the moment its fixed. In actual fact the speed information |
3070 | for the virtual channel can be propogated in both directions by | 3104 | for the virtual channel can be propogated in both directions by |
3071 | the RPN control message. This however rapidly gets nasty as we | 3105 | the RPN control message. This however rapidly gets nasty as we |
@@ -3077,6 +3111,8 @@ static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
3077 | static void gsmtty_throttle(struct tty_struct *tty) | 3111 | static void gsmtty_throttle(struct tty_struct *tty) |
3078 | { | 3112 | { |
3079 | struct gsm_dlci *dlci = tty->driver_data; | 3113 | struct gsm_dlci *dlci = tty->driver_data; |
3114 | if (dlci->state == DLCI_CLOSED) | ||
3115 | return; | ||
3080 | if (tty->termios.c_cflag & CRTSCTS) | 3116 | if (tty->termios.c_cflag & CRTSCTS) |
3081 | dlci->modem_tx &= ~TIOCM_DTR; | 3117 | dlci->modem_tx &= ~TIOCM_DTR; |
3082 | dlci->throttled = 1; | 3118 | dlci->throttled = 1; |
@@ -3087,6 +3123,8 @@ static void gsmtty_throttle(struct tty_struct *tty) | |||
3087 | static void gsmtty_unthrottle(struct tty_struct *tty) | 3123 | static void gsmtty_unthrottle(struct tty_struct *tty) |
3088 | { | 3124 | { |
3089 | struct gsm_dlci *dlci = tty->driver_data; | 3125 | struct gsm_dlci *dlci = tty->driver_data; |
3126 | if (dlci->state == DLCI_CLOSED) | ||
3127 | return; | ||
3090 | if (tty->termios.c_cflag & CRTSCTS) | 3128 | if (tty->termios.c_cflag & CRTSCTS) |
3091 | dlci->modem_tx |= TIOCM_DTR; | 3129 | dlci->modem_tx |= TIOCM_DTR; |
3092 | dlci->throttled = 0; | 3130 | dlci->throttled = 0; |
@@ -3098,6 +3136,8 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) | |||
3098 | { | 3136 | { |
3099 | struct gsm_dlci *dlci = tty->driver_data; | 3137 | struct gsm_dlci *dlci = tty->driver_data; |
3100 | int encode = 0; /* Off */ | 3138 | int encode = 0; /* Off */ |
3139 | if (dlci->state == DLCI_CLOSED) | ||
3140 | return -EINVAL; | ||
3101 | 3141 | ||
3102 | if (state == -1) /* "On indefinitely" - we can't encode this | 3142 | if (state == -1) /* "On indefinitely" - we can't encode this |
3103 | properly */ | 3143 | properly */ |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 19083efa2314..05e72bea9b07 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/file.h> | 49 | #include <linux/file.h> |
50 | #include <linux/uaccess.h> | 50 | #include <linux/uaccess.h> |
51 | #include <linux/module.h> | 51 | #include <linux/module.h> |
52 | #include <linux/ratelimit.h> | ||
52 | 53 | ||
53 | 54 | ||
54 | /* number of characters left in xmit buffer before select has we have room */ | 55 | /* number of characters left in xmit buffer before select has we have room */ |
@@ -100,7 +101,7 @@ struct n_tty_data { | |||
100 | struct mutex atomic_read_lock; | 101 | struct mutex atomic_read_lock; |
101 | struct mutex output_lock; | 102 | struct mutex output_lock; |
102 | struct mutex echo_lock; | 103 | struct mutex echo_lock; |
103 | spinlock_t read_lock; | 104 | raw_spinlock_t read_lock; |
104 | }; | 105 | }; |
105 | 106 | ||
106 | static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | 107 | static inline int tty_put_user(struct tty_struct *tty, unsigned char x, |
@@ -182,9 +183,9 @@ static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) | |||
182 | * The problem of stomping on the buffers ends here. | 183 | * The problem of stomping on the buffers ends here. |
183 | * Why didn't anyone see this one coming? --AJK | 184 | * Why didn't anyone see this one coming? --AJK |
184 | */ | 185 | */ |
185 | spin_lock_irqsave(&ldata->read_lock, flags); | 186 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
186 | put_tty_queue_nolock(c, ldata); | 187 | put_tty_queue_nolock(c, ldata); |
187 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 188 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
188 | } | 189 | } |
189 | 190 | ||
190 | /** | 191 | /** |
@@ -218,9 +219,9 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
218 | struct n_tty_data *ldata = tty->disc_data; | 219 | struct n_tty_data *ldata = tty->disc_data; |
219 | unsigned long flags; | 220 | unsigned long flags; |
220 | 221 | ||
221 | spin_lock_irqsave(&ldata->read_lock, flags); | 222 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
222 | ldata->read_head = ldata->read_tail = ldata->read_cnt = 0; | 223 | ldata->read_head = ldata->read_tail = ldata->read_cnt = 0; |
223 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 224 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
224 | 225 | ||
225 | mutex_lock(&ldata->echo_lock); | 226 | mutex_lock(&ldata->echo_lock); |
226 | ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0; | 227 | ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0; |
@@ -276,7 +277,7 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) | |||
276 | unsigned long flags; | 277 | unsigned long flags; |
277 | ssize_t n = 0; | 278 | ssize_t n = 0; |
278 | 279 | ||
279 | spin_lock_irqsave(&ldata->read_lock, flags); | 280 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
280 | if (!ldata->icanon) { | 281 | if (!ldata->icanon) { |
281 | n = ldata->read_cnt; | 282 | n = ldata->read_cnt; |
282 | } else if (ldata->canon_data) { | 283 | } else if (ldata->canon_data) { |
@@ -284,7 +285,7 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) | |||
284 | ldata->canon_head - ldata->read_tail : | 285 | ldata->canon_head - ldata->read_tail : |
285 | ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail); | 286 | ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail); |
286 | } | 287 | } |
287 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 288 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
288 | return n; | 289 | return n; |
289 | } | 290 | } |
290 | 291 | ||
@@ -915,19 +916,19 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
915 | kill_type = WERASE; | 916 | kill_type = WERASE; |
916 | else { | 917 | else { |
917 | if (!L_ECHO(tty)) { | 918 | if (!L_ECHO(tty)) { |
918 | spin_lock_irqsave(&ldata->read_lock, flags); | 919 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
919 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & | 920 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & |
920 | (N_TTY_BUF_SIZE - 1)); | 921 | (N_TTY_BUF_SIZE - 1)); |
921 | ldata->read_head = ldata->canon_head; | 922 | ldata->read_head = ldata->canon_head; |
922 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 923 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
923 | return; | 924 | return; |
924 | } | 925 | } |
925 | if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { | 926 | if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { |
926 | spin_lock_irqsave(&ldata->read_lock, flags); | 927 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
927 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & | 928 | ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & |
928 | (N_TTY_BUF_SIZE - 1)); | 929 | (N_TTY_BUF_SIZE - 1)); |
929 | ldata->read_head = ldata->canon_head; | 930 | ldata->read_head = ldata->canon_head; |
930 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 931 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
931 | finish_erasing(ldata); | 932 | finish_erasing(ldata); |
932 | echo_char(KILL_CHAR(tty), tty); | 933 | echo_char(KILL_CHAR(tty), tty); |
933 | /* Add a newline if ECHOK is on and ECHOKE is off. */ | 934 | /* Add a newline if ECHOK is on and ECHOKE is off. */ |
@@ -961,10 +962,10 @@ static void eraser(unsigned char c, struct tty_struct *tty) | |||
961 | break; | 962 | break; |
962 | } | 963 | } |
963 | cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1); | 964 | cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1); |
964 | spin_lock_irqsave(&ldata->read_lock, flags); | 965 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
965 | ldata->read_head = head; | 966 | ldata->read_head = head; |
966 | ldata->read_cnt -= cnt; | 967 | ldata->read_cnt -= cnt; |
967 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 968 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
968 | if (L_ECHO(tty)) { | 969 | if (L_ECHO(tty)) { |
969 | if (L_ECHOPRT(tty)) { | 970 | if (L_ECHOPRT(tty)) { |
970 | if (!ldata->erasing) { | 971 | if (!ldata->erasing) { |
@@ -1344,12 +1345,12 @@ send_signal: | |||
1344 | put_tty_queue(c, ldata); | 1345 | put_tty_queue(c, ldata); |
1345 | 1346 | ||
1346 | handle_newline: | 1347 | handle_newline: |
1347 | spin_lock_irqsave(&ldata->read_lock, flags); | 1348 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1348 | set_bit(ldata->read_head, ldata->read_flags); | 1349 | set_bit(ldata->read_head, ldata->read_flags); |
1349 | put_tty_queue_nolock(c, ldata); | 1350 | put_tty_queue_nolock(c, ldata); |
1350 | ldata->canon_head = ldata->read_head; | 1351 | ldata->canon_head = ldata->read_head; |
1351 | ldata->canon_data++; | 1352 | ldata->canon_data++; |
1352 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1353 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1353 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1354 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
1354 | if (waitqueue_active(&tty->read_wait)) | 1355 | if (waitqueue_active(&tty->read_wait)) |
1355 | wake_up_interruptible(&tty->read_wait); | 1356 | wake_up_interruptible(&tty->read_wait); |
@@ -1423,7 +1424,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1423 | unsigned long cpuflags; | 1424 | unsigned long cpuflags; |
1424 | 1425 | ||
1425 | if (ldata->real_raw) { | 1426 | if (ldata->real_raw) { |
1426 | spin_lock_irqsave(&ldata->read_lock, cpuflags); | 1427 | raw_spin_lock_irqsave(&ldata->read_lock, cpuflags); |
1427 | i = min(N_TTY_BUF_SIZE - ldata->read_cnt, | 1428 | i = min(N_TTY_BUF_SIZE - ldata->read_cnt, |
1428 | N_TTY_BUF_SIZE - ldata->read_head); | 1429 | N_TTY_BUF_SIZE - ldata->read_head); |
1429 | i = min(count, i); | 1430 | i = min(count, i); |
@@ -1439,7 +1440,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1439 | memcpy(ldata->read_buf + ldata->read_head, cp, i); | 1440 | memcpy(ldata->read_buf + ldata->read_head, cp, i); |
1440 | ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); | 1441 | ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); |
1441 | ldata->read_cnt += i; | 1442 | ldata->read_cnt += i; |
1442 | spin_unlock_irqrestore(&ldata->read_lock, cpuflags); | 1443 | raw_spin_unlock_irqrestore(&ldata->read_lock, cpuflags); |
1443 | } else { | 1444 | } else { |
1444 | for (i = count, p = cp, f = fp; i; i--, p++) { | 1445 | for (i = count, p = cp, f = fp; i; i--, p++) { |
1445 | if (f) | 1446 | if (f) |
@@ -1635,7 +1636,7 @@ static int n_tty_open(struct tty_struct *tty) | |||
1635 | mutex_init(&ldata->atomic_read_lock); | 1636 | mutex_init(&ldata->atomic_read_lock); |
1636 | mutex_init(&ldata->output_lock); | 1637 | mutex_init(&ldata->output_lock); |
1637 | mutex_init(&ldata->echo_lock); | 1638 | mutex_init(&ldata->echo_lock); |
1638 | spin_lock_init(&ldata->read_lock); | 1639 | raw_spin_lock_init(&ldata->read_lock); |
1639 | 1640 | ||
1640 | /* These are ugly. Currently a malloc failure here can panic */ | 1641 | /* These are ugly. Currently a malloc failure here can panic */ |
1641 | ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); | 1642 | ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); |
@@ -1703,10 +1704,10 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1703 | bool is_eof; | 1704 | bool is_eof; |
1704 | 1705 | ||
1705 | retval = 0; | 1706 | retval = 0; |
1706 | spin_lock_irqsave(&ldata->read_lock, flags); | 1707 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1707 | n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail); | 1708 | n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail); |
1708 | n = min(*nr, n); | 1709 | n = min(*nr, n); |
1709 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1710 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1710 | if (n) { | 1711 | if (n) { |
1711 | retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n); | 1712 | retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n); |
1712 | n -= retval; | 1713 | n -= retval; |
@@ -1714,13 +1715,13 @@ static int copy_from_read_buf(struct tty_struct *tty, | |||
1714 | ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty); | 1715 | ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty); |
1715 | tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n, | 1716 | tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n, |
1716 | ldata->icanon); | 1717 | ldata->icanon); |
1717 | spin_lock_irqsave(&ldata->read_lock, flags); | 1718 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1718 | ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1); | 1719 | ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1); |
1719 | ldata->read_cnt -= n; | 1720 | ldata->read_cnt -= n; |
1720 | /* Turn single EOF into zero-length read */ | 1721 | /* Turn single EOF into zero-length read */ |
1721 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt) | 1722 | if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt) |
1722 | n = 0; | 1723 | n = 0; |
1723 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1724 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1724 | *b += n; | 1725 | *b += n; |
1725 | *nr -= n; | 1726 | *nr -= n; |
1726 | } | 1727 | } |
@@ -1900,7 +1901,7 @@ do_it_again: | |||
1900 | 1901 | ||
1901 | if (ldata->icanon && !L_EXTPROC(tty)) { | 1902 | if (ldata->icanon && !L_EXTPROC(tty)) { |
1902 | /* N.B. avoid overrun if nr == 0 */ | 1903 | /* N.B. avoid overrun if nr == 0 */ |
1903 | spin_lock_irqsave(&ldata->read_lock, flags); | 1904 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1904 | while (nr && ldata->read_cnt) { | 1905 | while (nr && ldata->read_cnt) { |
1905 | int eol; | 1906 | int eol; |
1906 | 1907 | ||
@@ -1918,25 +1919,25 @@ do_it_again: | |||
1918 | if (--ldata->canon_data < 0) | 1919 | if (--ldata->canon_data < 0) |
1919 | ldata->canon_data = 0; | 1920 | ldata->canon_data = 0; |
1920 | } | 1921 | } |
1921 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1922 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1922 | 1923 | ||
1923 | if (!eol || (c != __DISABLED_CHAR)) { | 1924 | if (!eol || (c != __DISABLED_CHAR)) { |
1924 | if (tty_put_user(tty, c, b++)) { | 1925 | if (tty_put_user(tty, c, b++)) { |
1925 | retval = -EFAULT; | 1926 | retval = -EFAULT; |
1926 | b--; | 1927 | b--; |
1927 | spin_lock_irqsave(&ldata->read_lock, flags); | 1928 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1928 | break; | 1929 | break; |
1929 | } | 1930 | } |
1930 | nr--; | 1931 | nr--; |
1931 | } | 1932 | } |
1932 | if (eol) { | 1933 | if (eol) { |
1933 | tty_audit_push(tty); | 1934 | tty_audit_push(tty); |
1934 | spin_lock_irqsave(&ldata->read_lock, flags); | 1935 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1935 | break; | 1936 | break; |
1936 | } | 1937 | } |
1937 | spin_lock_irqsave(&ldata->read_lock, flags); | 1938 | raw_spin_lock_irqsave(&ldata->read_lock, flags); |
1938 | } | 1939 | } |
1939 | spin_unlock_irqrestore(&ldata->read_lock, flags); | 1940 | raw_spin_unlock_irqrestore(&ldata->read_lock, flags); |
1940 | if (retval) | 1941 | if (retval) |
1941 | break; | 1942 | break; |
1942 | } else { | 1943 | } else { |
@@ -2188,7 +2189,7 @@ struct tty_ldisc_ops tty_ldisc_N_TTY = { | |||
2188 | * n_tty_inherit_ops - inherit N_TTY methods | 2189 | * n_tty_inherit_ops - inherit N_TTY methods |
2189 | * @ops: struct tty_ldisc_ops where to save N_TTY methods | 2190 | * @ops: struct tty_ldisc_ops where to save N_TTY methods |
2190 | * | 2191 | * |
2191 | * Used by a generic struct tty_ldisc_ops to easily inherit N_TTY | 2192 | * Enables a 'subclass' line discipline to 'inherit' N_TTY |
2192 | * methods. | 2193 | * methods. |
2193 | */ | 2194 | */ |
2194 | 2195 | ||
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index a0c69ab04399..2dff19796157 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -827,15 +827,10 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
827 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 827 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
828 | int i, ret; | 828 | int i, ret; |
829 | 829 | ||
830 | if (unlikely(!tty)) { | ||
831 | DBG1("tty not open for port: %d?", index); | ||
832 | return 1; | ||
833 | } | ||
834 | |||
835 | read_mem32((u32 *) &size, addr, 4); | 830 | read_mem32((u32 *) &size, addr, 4); |
836 | /* DBG1( "%d bytes port: %d", size, index); */ | 831 | /* DBG1( "%d bytes port: %d", size, index); */ |
837 | 832 | ||
838 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | 833 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) { |
839 | DBG1("No room in tty, don't read data, don't ack interrupt, " | 834 | DBG1("No room in tty, don't read data, don't ack interrupt, " |
840 | "disable interrupt"); | 835 | "disable interrupt"); |
841 | 836 | ||
@@ -855,13 +850,14 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
855 | read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); | 850 | read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); |
856 | 851 | ||
857 | if (size == 1) { | 852 | if (size == 1) { |
858 | tty_insert_flip_char(tty, buf[0], TTY_NORMAL); | 853 | tty_insert_flip_char(&port->port, buf[0], TTY_NORMAL); |
859 | size = 0; | 854 | size = 0; |
860 | } else if (size < RECEIVE_BUF_MAX) { | 855 | } else if (size < RECEIVE_BUF_MAX) { |
861 | size -= tty_insert_flip_string(tty, (char *) buf, size); | 856 | size -= tty_insert_flip_string(&port->port, |
857 | (char *)buf, size); | ||
862 | } else { | 858 | } else { |
863 | i = tty_insert_flip_string(tty, \ | 859 | i = tty_insert_flip_string(&port->port, |
864 | (char *) buf, RECEIVE_BUF_MAX); | 860 | (char *)buf, RECEIVE_BUF_MAX); |
865 | size -= i; | 861 | size -= i; |
866 | offset += i; | 862 | offset += i; |
867 | } | 863 | } |
@@ -1276,15 +1272,11 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id) | |||
1276 | 1272 | ||
1277 | exit_handler: | 1273 | exit_handler: |
1278 | spin_unlock(&dc->spin_mutex); | 1274 | spin_unlock(&dc->spin_mutex); |
1279 | for (a = 0; a < NOZOMI_MAX_PORTS; a++) { | 1275 | |
1280 | struct tty_struct *tty; | 1276 | for (a = 0; a < NOZOMI_MAX_PORTS; a++) |
1281 | if (test_and_clear_bit(a, &dc->flip)) { | 1277 | if (test_and_clear_bit(a, &dc->flip)) |
1282 | tty = tty_port_tty_get(&dc->port[a].port); | 1278 | tty_flip_buffer_push(&dc->port[a].port); |
1283 | if (tty) | 1279 | |
1284 | tty_flip_buffer_push(tty); | ||
1285 | tty_kref_put(tty); | ||
1286 | } | ||
1287 | } | ||
1288 | return IRQ_HANDLED; | 1280 | return IRQ_HANDLED; |
1289 | none: | 1281 | none: |
1290 | spin_unlock(&dc->spin_mutex); | 1282 | spin_unlock(&dc->spin_mutex); |
@@ -1687,12 +1679,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1687 | 1679 | ||
1688 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); | 1680 | rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count); |
1689 | 1681 | ||
1690 | /* notify card */ | ||
1691 | if (unlikely(dc == NULL)) { | ||
1692 | DBG1("No device context?"); | ||
1693 | goto exit; | ||
1694 | } | ||
1695 | |||
1696 | spin_lock_irqsave(&dc->spin_mutex, flags); | 1682 | spin_lock_irqsave(&dc->spin_mutex, flags); |
1697 | /* CTS is only valid on the modem channel */ | 1683 | /* CTS is only valid on the modem channel */ |
1698 | if (port == &(dc->port[PORT_MDM])) { | 1684 | if (port == &(dc->port[PORT_MDM])) { |
@@ -1708,7 +1694,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | |||
1708 | } | 1694 | } |
1709 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | 1695 | spin_unlock_irqrestore(&dc->spin_mutex, flags); |
1710 | 1696 | ||
1711 | exit: | ||
1712 | return rval; | 1697 | return rval; |
1713 | } | 1698 | } |
1714 | 1699 | ||
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 79ff3a5e925d..c24b4db243b9 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -38,16 +38,18 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
38 | if (tty->driver->subtype == PTY_TYPE_MASTER) | 38 | if (tty->driver->subtype == PTY_TYPE_MASTER) |
39 | WARN_ON(tty->count > 1); | 39 | WARN_ON(tty->count > 1); |
40 | else { | 40 | else { |
41 | if (test_bit(TTY_IO_ERROR, &tty->flags)) | ||
42 | return; | ||
41 | if (tty->count > 2) | 43 | if (tty->count > 2) |
42 | return; | 44 | return; |
43 | } | 45 | } |
46 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
44 | wake_up_interruptible(&tty->read_wait); | 47 | wake_up_interruptible(&tty->read_wait); |
45 | wake_up_interruptible(&tty->write_wait); | 48 | wake_up_interruptible(&tty->write_wait); |
46 | tty->packet = 0; | 49 | tty->packet = 0; |
47 | /* Review - krefs on tty_link ?? */ | 50 | /* Review - krefs on tty_link ?? */ |
48 | if (!tty->link) | 51 | if (!tty->link) |
49 | return; | 52 | return; |
50 | tty->link->packet = 0; | ||
51 | set_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 53 | set_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
52 | wake_up_interruptible(&tty->link->read_wait); | 54 | wake_up_interruptible(&tty->link->read_wait); |
53 | wake_up_interruptible(&tty->link->write_wait); | 55 | wake_up_interruptible(&tty->link->write_wait); |
@@ -55,9 +57,10 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
55 | set_bit(TTY_OTHER_CLOSED, &tty->flags); | 57 | set_bit(TTY_OTHER_CLOSED, &tty->flags); |
56 | #ifdef CONFIG_UNIX98_PTYS | 58 | #ifdef CONFIG_UNIX98_PTYS |
57 | if (tty->driver == ptm_driver) { | 59 | if (tty->driver == ptm_driver) { |
58 | mutex_lock(&devpts_mutex); | 60 | mutex_lock(&devpts_mutex); |
59 | devpts_pty_kill(tty->link->driver_data); | 61 | if (tty->link->driver_data) |
60 | mutex_unlock(&devpts_mutex); | 62 | devpts_pty_kill(tty->link->driver_data); |
63 | mutex_unlock(&devpts_mutex); | ||
61 | } | 64 | } |
62 | #endif | 65 | #endif |
63 | tty_unlock(tty); | 66 | tty_unlock(tty); |
@@ -120,10 +123,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c) | |||
120 | 123 | ||
121 | if (c > 0) { | 124 | if (c > 0) { |
122 | /* Stuff the data into the input queue of the other end */ | 125 | /* Stuff the data into the input queue of the other end */ |
123 | c = tty_insert_flip_string(to, buf, c); | 126 | c = tty_insert_flip_string(to->port, buf, c); |
124 | /* And shovel */ | 127 | /* And shovel */ |
125 | if (c) { | 128 | if (c) { |
126 | tty_flip_buffer_push(to); | 129 | tty_flip_buffer_push(to->port); |
127 | tty_wakeup(tty); | 130 | tty_wakeup(tty); |
128 | } | 131 | } |
129 | } | 132 | } |
@@ -246,14 +249,17 @@ static int pty_open(struct tty_struct *tty, struct file *filp) | |||
246 | if (!tty || !tty->link) | 249 | if (!tty || !tty->link) |
247 | goto out; | 250 | goto out; |
248 | 251 | ||
252 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
253 | |||
249 | retval = -EIO; | 254 | retval = -EIO; |
250 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | 255 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) |
251 | goto out; | 256 | goto out; |
252 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) | 257 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) |
253 | goto out; | 258 | goto out; |
254 | if (tty->link->count != 1) | 259 | if (tty->driver->subtype == PTY_TYPE_SLAVE && tty->link->count != 1) |
255 | goto out; | 260 | goto out; |
256 | 261 | ||
262 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
257 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 263 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
258 | set_bit(TTY_THROTTLED, &tty->flags); | 264 | set_bit(TTY_THROTTLED, &tty->flags); |
259 | retval = 0; | 265 | retval = 0; |
@@ -663,7 +669,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
663 | * Allocate a unix98 pty master device from the ptmx driver. | 669 | * Allocate a unix98 pty master device from the ptmx driver. |
664 | * | 670 | * |
665 | * Locking: tty_mutex protects the init_dev work. tty->count should | 671 | * Locking: tty_mutex protects the init_dev work. tty->count should |
666 | * protect the rest. | 672 | * protect the rest. |
667 | * allocated_ptys_lock handles the list of free pty numbers | 673 | * allocated_ptys_lock handles the list of free pty numbers |
668 | */ | 674 | */ |
669 | 675 | ||
@@ -704,6 +710,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
704 | mutex_unlock(&tty_mutex); | 710 | mutex_unlock(&tty_mutex); |
705 | 711 | ||
706 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 712 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
713 | tty->driver_data = inode; | ||
707 | 714 | ||
708 | tty_add_file(tty, filp); | 715 | tty_add_file(tty, filp); |
709 | 716 | ||
@@ -714,14 +721,13 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
714 | retval = PTR_ERR(slave_inode); | 721 | retval = PTR_ERR(slave_inode); |
715 | goto err_release; | 722 | goto err_release; |
716 | } | 723 | } |
724 | tty->link->driver_data = slave_inode; | ||
717 | 725 | ||
718 | retval = ptm_driver->ops->open(tty, filp); | 726 | retval = ptm_driver->ops->open(tty, filp); |
719 | if (retval) | 727 | if (retval) |
720 | goto err_release; | 728 | goto err_release; |
721 | 729 | ||
722 | tty_unlock(tty); | 730 | tty_unlock(tty); |
723 | tty->driver_data = inode; | ||
724 | tty->link->driver_data = slave_inode; | ||
725 | return 0; | 731 | return 0; |
726 | err_release: | 732 | err_release: |
727 | tty_unlock(tty); | 733 | tty_unlock(tty); |
@@ -797,7 +803,7 @@ static void __init unix98_pty_init(void) | |||
797 | cdev_init(&ptmx_cdev, &ptmx_fops); | 803 | cdev_init(&ptmx_cdev, &ptmx_fops); |
798 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | 804 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || |
799 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | 805 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) |
800 | panic("Couldn't register /dev/ptmx driver\n"); | 806 | panic("Couldn't register /dev/ptmx driver"); |
801 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | 807 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); |
802 | } | 808 | } |
803 | 809 | ||
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index e42009a00529..1d270034bfc3 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #undef REV_PCI_ORDER | 55 | #undef REV_PCI_ORDER |
56 | #undef ROCKET_DEBUG_IO | 56 | #undef ROCKET_DEBUG_IO |
57 | 57 | ||
58 | #define POLL_PERIOD HZ/100 /* Polling period .01 seconds (10ms) */ | 58 | #define POLL_PERIOD (HZ/100) /* Polling period .01 seconds (10ms) */ |
59 | 59 | ||
60 | /****** Kernel includes ******/ | 60 | /****** Kernel includes ******/ |
61 | 61 | ||
@@ -315,9 +315,8 @@ static inline int rocket_paranoia_check(struct r_port *info, | |||
315 | * that receive data is present on a serial port. Pulls data from FIFO, moves it into the | 315 | * that receive data is present on a serial port. Pulls data from FIFO, moves it into the |
316 | * tty layer. | 316 | * tty layer. |
317 | */ | 317 | */ |
318 | static void rp_do_receive(struct r_port *info, | 318 | static void rp_do_receive(struct r_port *info, CHANNEL_t *cp, |
319 | struct tty_struct *tty, | 319 | unsigned int ChanStatus) |
320 | CHANNEL_t * cp, unsigned int ChanStatus) | ||
321 | { | 320 | { |
322 | unsigned int CharNStat; | 321 | unsigned int CharNStat; |
323 | int ToRecv, wRecv, space; | 322 | int ToRecv, wRecv, space; |
@@ -379,7 +378,8 @@ static void rp_do_receive(struct r_port *info, | |||
379 | flag = TTY_OVERRUN; | 378 | flag = TTY_OVERRUN; |
380 | else | 379 | else |
381 | flag = TTY_NORMAL; | 380 | flag = TTY_NORMAL; |
382 | tty_insert_flip_char(tty, CharNStat & 0xff, flag); | 381 | tty_insert_flip_char(&info->port, CharNStat & 0xff, |
382 | flag); | ||
383 | ToRecv--; | 383 | ToRecv--; |
384 | } | 384 | } |
385 | 385 | ||
@@ -399,7 +399,7 @@ static void rp_do_receive(struct r_port *info, | |||
399 | * characters at time by doing repeated word IO | 399 | * characters at time by doing repeated word IO |
400 | * transfer. | 400 | * transfer. |
401 | */ | 401 | */ |
402 | space = tty_prepare_flip_string(tty, &cbuf, ToRecv); | 402 | space = tty_prepare_flip_string(&info->port, &cbuf, ToRecv); |
403 | if (space < ToRecv) { | 403 | if (space < ToRecv) { |
404 | #ifdef ROCKET_DEBUG_RECEIVE | 404 | #ifdef ROCKET_DEBUG_RECEIVE |
405 | printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space); | 405 | printk(KERN_INFO "rp_do_receive:insufficient space ToRecv=%d space=%d\n", ToRecv, space); |
@@ -415,7 +415,7 @@ static void rp_do_receive(struct r_port *info, | |||
415 | cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); | 415 | cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp)); |
416 | } | 416 | } |
417 | /* Push the data up to the tty layer */ | 417 | /* Push the data up to the tty layer */ |
418 | tty_flip_buffer_push(tty); | 418 | tty_flip_buffer_push(&info->port); |
419 | } | 419 | } |
420 | 420 | ||
421 | /* | 421 | /* |
@@ -494,7 +494,6 @@ static void rp_do_transmit(struct r_port *info) | |||
494 | static void rp_handle_port(struct r_port *info) | 494 | static void rp_handle_port(struct r_port *info) |
495 | { | 495 | { |
496 | CHANNEL_t *cp; | 496 | CHANNEL_t *cp; |
497 | struct tty_struct *tty; | ||
498 | unsigned int IntMask, ChanStatus; | 497 | unsigned int IntMask, ChanStatus; |
499 | 498 | ||
500 | if (!info) | 499 | if (!info) |
@@ -505,12 +504,7 @@ static void rp_handle_port(struct r_port *info) | |||
505 | "info->flags & NOT_INIT\n"); | 504 | "info->flags & NOT_INIT\n"); |
506 | return; | 505 | return; |
507 | } | 506 | } |
508 | tty = tty_port_tty_get(&info->port); | 507 | |
509 | if (!tty) { | ||
510 | printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " | ||
511 | "tty==NULL\n"); | ||
512 | return; | ||
513 | } | ||
514 | cp = &info->channel; | 508 | cp = &info->channel; |
515 | 509 | ||
516 | IntMask = sGetChanIntID(cp) & info->intmask; | 510 | IntMask = sGetChanIntID(cp) & info->intmask; |
@@ -519,7 +513,7 @@ static void rp_handle_port(struct r_port *info) | |||
519 | #endif | 513 | #endif |
520 | ChanStatus = sGetChanStatus(cp); | 514 | ChanStatus = sGetChanStatus(cp); |
521 | if (IntMask & RXF_TRIG) { /* Rx FIFO trigger level */ | 515 | if (IntMask & RXF_TRIG) { /* Rx FIFO trigger level */ |
522 | rp_do_receive(info, tty, cp, ChanStatus); | 516 | rp_do_receive(info, cp, ChanStatus); |
523 | } | 517 | } |
524 | if (IntMask & DELTA_CD) { /* CD change */ | 518 | if (IntMask & DELTA_CD) { /* CD change */ |
525 | #if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP)) | 519 | #if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP)) |
@@ -527,10 +521,15 @@ static void rp_handle_port(struct r_port *info) | |||
527 | (ChanStatus & CD_ACT) ? "on" : "off"); | 521 | (ChanStatus & CD_ACT) ? "on" : "off"); |
528 | #endif | 522 | #endif |
529 | if (!(ChanStatus & CD_ACT) && info->cd_status) { | 523 | if (!(ChanStatus & CD_ACT) && info->cd_status) { |
524 | struct tty_struct *tty; | ||
530 | #ifdef ROCKET_DEBUG_HANGUP | 525 | #ifdef ROCKET_DEBUG_HANGUP |
531 | printk(KERN_INFO "CD drop, calling hangup.\n"); | 526 | printk(KERN_INFO "CD drop, calling hangup.\n"); |
532 | #endif | 527 | #endif |
533 | tty_hangup(tty); | 528 | tty = tty_port_tty_get(&info->port); |
529 | if (tty) { | ||
530 | tty_hangup(tty); | ||
531 | tty_kref_put(tty); | ||
532 | } | ||
534 | } | 533 | } |
535 | info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; | 534 | info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; |
536 | wake_up_interruptible(&info->port.open_wait); | 535 | wake_up_interruptible(&info->port.open_wait); |
@@ -543,7 +542,6 @@ static void rp_handle_port(struct r_port *info) | |||
543 | printk(KERN_INFO "DSR change...\n"); | 542 | printk(KERN_INFO "DSR change...\n"); |
544 | } | 543 | } |
545 | #endif | 544 | #endif |
546 | tty_kref_put(tty); | ||
547 | } | 545 | } |
548 | 546 | ||
549 | /* | 547 | /* |
@@ -1758,8 +1756,29 @@ static void rp_flush_buffer(struct tty_struct *tty) | |||
1758 | 1756 | ||
1759 | #ifdef CONFIG_PCI | 1757 | #ifdef CONFIG_PCI |
1760 | 1758 | ||
1761 | static struct pci_device_id __used rocket_pci_ids[] = { | 1759 | static DEFINE_PCI_DEVICE_TABLE(rocket_pci_ids) = { |
1762 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, | 1760 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4QUAD) }, |
1761 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8OCTA) }, | ||
1762 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP8OCTA) }, | ||
1763 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8INTF) }, | ||
1764 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP8INTF) }, | ||
1765 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8J) }, | ||
1766 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4J) }, | ||
1767 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP8SNI) }, | ||
1768 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP16SNI) }, | ||
1769 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP16INTF) }, | ||
1770 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP16INTF) }, | ||
1771 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_CRP16INTF) }, | ||
1772 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP32INTF) }, | ||
1773 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_URP32INTF) }, | ||
1774 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RPP4) }, | ||
1775 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RPP8) }, | ||
1776 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP2_232) }, | ||
1777 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP2_422) }, | ||
1778 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP6M) }, | ||
1779 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_RP4M) }, | ||
1780 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_UPCI_RM3_8PORT) }, | ||
1781 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_DEVICE_ID_UPCI_RM3_4PORT) }, | ||
1763 | { } | 1782 | { } |
1764 | }; | 1783 | }; |
1765 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); | 1784 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); |
@@ -1781,7 +1800,8 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1781 | WordIO_t ConfigIO = 0; | 1800 | WordIO_t ConfigIO = 0; |
1782 | ByteIO_t UPCIRingInd = 0; | 1801 | ByteIO_t UPCIRingInd = 0; |
1783 | 1802 | ||
1784 | if (!dev || pci_enable_device(dev)) | 1803 | if (!dev || !pci_match_id(rocket_pci_ids, dev) || |
1804 | pci_enable_device(dev)) | ||
1785 | return 0; | 1805 | return 0; |
1786 | 1806 | ||
1787 | rcktpt_io_addr[i] = pci_resource_start(dev, 0); | 1807 | rcktpt_io_addr[i] = pci_resource_start(dev, 0); |
diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index a44345a2dbb4..c7e8b60b6177 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c | |||
@@ -85,7 +85,6 @@ static void serial21285_enable_ms(struct uart_port *port) | |||
85 | static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) | 85 | static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) |
86 | { | 86 | { |
87 | struct uart_port *port = dev_id; | 87 | struct uart_port *port = dev_id; |
88 | struct tty_struct *tty = port->state->port.tty; | ||
89 | unsigned int status, ch, flag, rxs, max_count = 256; | 88 | unsigned int status, ch, flag, rxs, max_count = 256; |
90 | 89 | ||
91 | status = *CSR_UARTFLG; | 90 | status = *CSR_UARTFLG; |
@@ -115,7 +114,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id) | |||
115 | 114 | ||
116 | status = *CSR_UARTFLG; | 115 | status = *CSR_UARTFLG; |
117 | } | 116 | } |
118 | tty_flip_buffer_push(tty); | 117 | tty_flip_buffer_push(&port->state->port); |
119 | 118 | ||
120 | return IRQ_HANDLED; | 119 | return IRQ_HANDLED; |
121 | } | 120 | } |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index f99a84526f82..49399470794d 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
@@ -262,8 +262,7 @@ static void rs_start(struct tty_struct *tty) | |||
262 | local_irq_restore(flags); | 262 | local_irq_restore(flags); |
263 | } | 263 | } |
264 | 264 | ||
265 | static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | 265 | static void receive_chars(struct m68k_serial *info, unsigned short rx) |
266 | unsigned short rx) | ||
267 | { | 266 | { |
268 | m68328_uart *uart = &uart_addr[info->line]; | 267 | m68328_uart *uart = &uart_addr[info->line]; |
269 | unsigned char ch, flag; | 268 | unsigned char ch, flag; |
@@ -293,9 +292,6 @@ static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | |||
293 | } | 292 | } |
294 | } | 293 | } |
295 | 294 | ||
296 | if(!tty) | ||
297 | goto clear_and_exit; | ||
298 | |||
299 | flag = TTY_NORMAL; | 295 | flag = TTY_NORMAL; |
300 | 296 | ||
301 | if (rx & URX_PARITY_ERROR) | 297 | if (rx & URX_PARITY_ERROR) |
@@ -305,15 +301,12 @@ static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, | |||
305 | else if (rx & URX_FRAME_ERROR) | 301 | else if (rx & URX_FRAME_ERROR) |
306 | flag = TTY_FRAME; | 302 | flag = TTY_FRAME; |
307 | 303 | ||
308 | tty_insert_flip_char(tty, ch, flag); | 304 | tty_insert_flip_char(&info->tport, ch, flag); |
309 | #ifndef CONFIG_XCOPILOT_BUGS | 305 | #ifndef CONFIG_XCOPILOT_BUGS |
310 | } while((rx = uart->urx.w) & URX_DATA_READY); | 306 | } while((rx = uart->urx.w) & URX_DATA_READY); |
311 | #endif | 307 | #endif |
312 | 308 | ||
313 | tty_schedule_flip(tty); | 309 | tty_schedule_flip(&info->tport); |
314 | |||
315 | clear_and_exit: | ||
316 | return; | ||
317 | } | 310 | } |
318 | 311 | ||
319 | static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) | 312 | static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) |
@@ -367,11 +360,11 @@ irqreturn_t rs_interrupt(int irq, void *dev_id) | |||
367 | tx = uart->utx.w; | 360 | tx = uart->utx.w; |
368 | 361 | ||
369 | if (rx & URX_DATA_READY) | 362 | if (rx & URX_DATA_READY) |
370 | receive_chars(info, tty, rx); | 363 | receive_chars(info, rx); |
371 | if (tx & UTX_TX_AVAIL) | 364 | if (tx & UTX_TX_AVAIL) |
372 | transmit_chars(info, tty); | 365 | transmit_chars(info, tty); |
373 | #else | 366 | #else |
374 | receive_chars(info, tty, rx); | 367 | receive_chars(info, rx); |
375 | #endif | 368 | #endif |
376 | tty_kref_put(tty); | 369 | tty_kref_put(tty); |
377 | 370 | ||
@@ -1009,7 +1002,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1009 | m68328_uart *uart = &uart_addr[info->line]; | 1002 | m68328_uart *uart = &uart_addr[info->line]; |
1010 | unsigned long flags; | 1003 | unsigned long flags; |
1011 | 1004 | ||
1012 | if (!info || serial_paranoia_check(info, tty->name, "rs_close")) | 1005 | if (serial_paranoia_check(info, tty->name, "rs_close")) |
1013 | return; | 1006 | return; |
1014 | 1007 | ||
1015 | local_irq_save(flags); | 1008 | local_irq_save(flags); |
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index f9320437a649..0efc815a4968 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c | |||
@@ -239,13 +239,6 @@ static const struct serial8250_config uart_config[] = { | |||
239 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 239 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, |
240 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, | 240 | .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, |
241 | }, | 241 | }, |
242 | [PORT_RM9000] = { | ||
243 | .name = "RM9000", | ||
244 | .fifo_size = 16, | ||
245 | .tx_loadsz = 16, | ||
246 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | ||
247 | .flags = UART_CAP_FIFO, | ||
248 | }, | ||
249 | [PORT_OCTEON] = { | 242 | [PORT_OCTEON] = { |
250 | .name = "OCTEON", | 243 | .name = "OCTEON", |
251 | .fifo_size = 64, | 244 | .fifo_size = 64, |
@@ -324,9 +317,9 @@ static void default_serial_dl_write(struct uart_8250_port *up, int value) | |||
324 | serial_out(up, UART_DLM, value >> 8 & 0xff); | 317 | serial_out(up, UART_DLM, value >> 8 & 0xff); |
325 | } | 318 | } |
326 | 319 | ||
327 | #ifdef CONFIG_MIPS_ALCHEMY | 320 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) |
328 | 321 | ||
329 | /* Au1x00 UART hardware has a weird register layout */ | 322 | /* Au1x00/RT288x UART hardware has a weird register layout */ |
330 | static const u8 au_io_in_map[] = { | 323 | static const u8 au_io_in_map[] = { |
331 | [UART_RX] = 0, | 324 | [UART_RX] = 0, |
332 | [UART_IER] = 2, | 325 | [UART_IER] = 2, |
@@ -370,56 +363,6 @@ static void au_serial_dl_write(struct uart_8250_port *up, int value) | |||
370 | 363 | ||
371 | #endif | 364 | #endif |
372 | 365 | ||
373 | #ifdef CONFIG_SERIAL_8250_RM9K | ||
374 | |||
375 | static const u8 | ||
376 | regmap_in[8] = { | ||
377 | [UART_RX] = 0x00, | ||
378 | [UART_IER] = 0x0c, | ||
379 | [UART_IIR] = 0x14, | ||
380 | [UART_LCR] = 0x1c, | ||
381 | [UART_MCR] = 0x20, | ||
382 | [UART_LSR] = 0x24, | ||
383 | [UART_MSR] = 0x28, | ||
384 | [UART_SCR] = 0x2c | ||
385 | }, | ||
386 | regmap_out[8] = { | ||
387 | [UART_TX] = 0x04, | ||
388 | [UART_IER] = 0x0c, | ||
389 | [UART_FCR] = 0x18, | ||
390 | [UART_LCR] = 0x1c, | ||
391 | [UART_MCR] = 0x20, | ||
392 | [UART_LSR] = 0x24, | ||
393 | [UART_MSR] = 0x28, | ||
394 | [UART_SCR] = 0x2c | ||
395 | }; | ||
396 | |||
397 | static unsigned int rm9k_serial_in(struct uart_port *p, int offset) | ||
398 | { | ||
399 | offset = regmap_in[offset] << p->regshift; | ||
400 | return readl(p->membase + offset); | ||
401 | } | ||
402 | |||
403 | static void rm9k_serial_out(struct uart_port *p, int offset, int value) | ||
404 | { | ||
405 | offset = regmap_out[offset] << p->regshift; | ||
406 | writel(value, p->membase + offset); | ||
407 | } | ||
408 | |||
409 | static int rm9k_serial_dl_read(struct uart_8250_port *up) | ||
410 | { | ||
411 | return ((__raw_readl(up->port.membase + 0x10) << 8) | | ||
412 | (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff; | ||
413 | } | ||
414 | |||
415 | static void rm9k_serial_dl_write(struct uart_8250_port *up, int value) | ||
416 | { | ||
417 | __raw_writel(value, up->port.membase + 0x08); | ||
418 | __raw_writel(value >> 8, up->port.membase + 0x10); | ||
419 | } | ||
420 | |||
421 | #endif | ||
422 | |||
423 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) | 366 | static unsigned int hub6_serial_in(struct uart_port *p, int offset) |
424 | { | 367 | { |
425 | offset = offset << p->regshift; | 368 | offset = offset << p->regshift; |
@@ -497,16 +440,7 @@ static void set_io_from_upio(struct uart_port *p) | |||
497 | p->serial_out = mem32_serial_out; | 440 | p->serial_out = mem32_serial_out; |
498 | break; | 441 | break; |
499 | 442 | ||
500 | #ifdef CONFIG_SERIAL_8250_RM9K | 443 | #if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X) |
501 | case UPIO_RM9000: | ||
502 | p->serial_in = rm9k_serial_in; | ||
503 | p->serial_out = rm9k_serial_out; | ||
504 | up->dl_read = rm9k_serial_dl_read; | ||
505 | up->dl_write = rm9k_serial_dl_write; | ||
506 | break; | ||
507 | #endif | ||
508 | |||
509 | #ifdef CONFIG_MIPS_ALCHEMY | ||
510 | case UPIO_AU: | 444 | case UPIO_AU: |
511 | p->serial_in = au_serial_in; | 445 | p->serial_in = au_serial_in; |
512 | p->serial_out = au_serial_out; | 446 | p->serial_out = au_serial_out; |
@@ -1341,7 +1275,9 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1341 | struct uart_8250_port *up = | 1275 | struct uart_8250_port *up = |
1342 | container_of(port, struct uart_8250_port, port); | 1276 | container_of(port, struct uart_8250_port, port); |
1343 | 1277 | ||
1344 | if (!(up->ier & UART_IER_THRI)) { | 1278 | if (up->dma && !serial8250_tx_dma(up)) { |
1279 | return; | ||
1280 | } else if (!(up->ier & UART_IER_THRI)) { | ||
1345 | up->ier |= UART_IER_THRI; | 1281 | up->ier |= UART_IER_THRI; |
1346 | serial_port_out(port, UART_IER, up->ier); | 1282 | serial_port_out(port, UART_IER, up->ier); |
1347 | 1283 | ||
@@ -1349,9 +1285,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
1349 | unsigned char lsr; | 1285 | unsigned char lsr; |
1350 | lsr = serial_in(up, UART_LSR); | 1286 | lsr = serial_in(up, UART_LSR); |
1351 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1287 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1352 | if ((port->type == PORT_RM9000) ? | 1288 | if (lsr & UART_LSR_TEMT) |
1353 | (lsr & UART_LSR_THRE) : | ||
1354 | (lsr & UART_LSR_TEMT)) | ||
1355 | serial8250_tx_chars(up); | 1289 | serial8250_tx_chars(up); |
1356 | } | 1290 | } |
1357 | } | 1291 | } |
@@ -1397,7 +1331,6 @@ unsigned char | |||
1397 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) | 1331 | serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr) |
1398 | { | 1332 | { |
1399 | struct uart_port *port = &up->port; | 1333 | struct uart_port *port = &up->port; |
1400 | struct tty_struct *tty = port->state->port.tty; | ||
1401 | unsigned char ch; | 1334 | unsigned char ch; |
1402 | int max_count = 256; | 1335 | int max_count = 256; |
1403 | char flag; | 1336 | char flag; |
@@ -1462,7 +1395,7 @@ ignore_char: | |||
1462 | lsr = serial_in(up, UART_LSR); | 1395 | lsr = serial_in(up, UART_LSR); |
1463 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); | 1396 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); |
1464 | spin_unlock(&port->lock); | 1397 | spin_unlock(&port->lock); |
1465 | tty_flip_buffer_push(tty); | 1398 | tty_flip_buffer_push(&port->state->port); |
1466 | spin_lock(&port->lock); | 1399 | spin_lock(&port->lock); |
1467 | return lsr; | 1400 | return lsr; |
1468 | } | 1401 | } |
@@ -1547,6 +1480,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1547 | unsigned long flags; | 1480 | unsigned long flags; |
1548 | struct uart_8250_port *up = | 1481 | struct uart_8250_port *up = |
1549 | container_of(port, struct uart_8250_port, port); | 1482 | container_of(port, struct uart_8250_port, port); |
1483 | int dma_err = 0; | ||
1550 | 1484 | ||
1551 | if (iir & UART_IIR_NO_INT) | 1485 | if (iir & UART_IIR_NO_INT) |
1552 | return 0; | 1486 | return 0; |
@@ -1557,8 +1491,13 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) | |||
1557 | 1491 | ||
1558 | DEBUG_INTR("status = %x...", status); | 1492 | DEBUG_INTR("status = %x...", status); |
1559 | 1493 | ||
1560 | if (status & (UART_LSR_DR | UART_LSR_BI)) | 1494 | if (status & (UART_LSR_DR | UART_LSR_BI)) { |
1561 | status = serial8250_rx_chars(up, status); | 1495 | if (up->dma) |
1496 | dma_err = serial8250_rx_dma(up, iir); | ||
1497 | |||
1498 | if (!up->dma || dma_err) | ||
1499 | status = serial8250_rx_chars(up, status); | ||
1500 | } | ||
1562 | serial8250_modem_status(up); | 1501 | serial8250_modem_status(up); |
1563 | if (status & UART_LSR_THRE) | 1502 | if (status & UART_LSR_THRE) |
1564 | serial8250_tx_chars(up); | 1503 | serial8250_tx_chars(up); |
@@ -1991,9 +1930,12 @@ static int serial8250_startup(struct uart_port *port) | |||
1991 | if (port->type == PORT_8250_CIR) | 1930 | if (port->type == PORT_8250_CIR) |
1992 | return -ENODEV; | 1931 | return -ENODEV; |
1993 | 1932 | ||
1994 | port->fifosize = uart_config[up->port.type].fifo_size; | 1933 | if (!port->fifosize) |
1995 | up->tx_loadsz = uart_config[up->port.type].tx_loadsz; | 1934 | port->fifosize = uart_config[port->type].fifo_size; |
1996 | up->capabilities = uart_config[up->port.type].flags; | 1935 | if (!up->tx_loadsz) |
1936 | up->tx_loadsz = uart_config[port->type].tx_loadsz; | ||
1937 | if (!up->capabilities) | ||
1938 | up->capabilities = uart_config[port->type].flags; | ||
1997 | up->mcr = 0; | 1939 | up->mcr = 0; |
1998 | 1940 | ||
1999 | if (port->iotype != up->cur_iotype) | 1941 | if (port->iotype != up->cur_iotype) |
@@ -2198,6 +2140,18 @@ dont_test_tx_en: | |||
2198 | up->msr_saved_flags = 0; | 2140 | up->msr_saved_flags = 0; |
2199 | 2141 | ||
2200 | /* | 2142 | /* |
2143 | * Request DMA channels for both RX and TX. | ||
2144 | */ | ||
2145 | if (up->dma) { | ||
2146 | retval = serial8250_request_dma(up); | ||
2147 | if (retval) { | ||
2148 | pr_warn_ratelimited("ttyS%d - failed to request DMA\n", | ||
2149 | serial_index(port)); | ||
2150 | up->dma = NULL; | ||
2151 | } | ||
2152 | } | ||
2153 | |||
2154 | /* | ||
2201 | * Finally, enable interrupts. Note: Modem status interrupts | 2155 | * Finally, enable interrupts. Note: Modem status interrupts |
2202 | * are set via set_termios(), which will be occurring imminently | 2156 | * are set via set_termios(), which will be occurring imminently |
2203 | * anyway, so we don't enable them here. | 2157 | * anyway, so we don't enable them here. |
@@ -2230,6 +2184,9 @@ static void serial8250_shutdown(struct uart_port *port) | |||
2230 | up->ier = 0; | 2184 | up->ier = 0; |
2231 | serial_port_out(port, UART_IER, 0); | 2185 | serial_port_out(port, UART_IER, 0); |
2232 | 2186 | ||
2187 | if (up->dma) | ||
2188 | serial8250_release_dma(up); | ||
2189 | |||
2233 | spin_lock_irqsave(&port->lock, flags); | 2190 | spin_lock_irqsave(&port->lock, flags); |
2234 | if (port->flags & UPF_FOURPORT) { | 2191 | if (port->flags & UPF_FOURPORT) { |
2235 | /* reset interrupts on the AST Fourport board */ | 2192 | /* reset interrupts on the AST Fourport board */ |
@@ -2826,9 +2783,12 @@ static void | |||
2826 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) | 2783 | serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type) |
2827 | { | 2784 | { |
2828 | up->port.type = type; | 2785 | up->port.type = type; |
2829 | up->port.fifosize = uart_config[type].fifo_size; | 2786 | if (!up->port.fifosize) |
2830 | up->capabilities = uart_config[type].flags; | 2787 | up->port.fifosize = uart_config[type].fifo_size; |
2831 | up->tx_loadsz = uart_config[type].tx_loadsz; | 2788 | if (!up->tx_loadsz) |
2789 | up->tx_loadsz = uart_config[type].tx_loadsz; | ||
2790 | if (!up->capabilities) | ||
2791 | up->capabilities = uart_config[type].flags; | ||
2832 | } | 2792 | } |
2833 | 2793 | ||
2834 | static void __init | 2794 | static void __init |
@@ -3262,6 +3222,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3262 | uart->bugs = up->bugs; | 3222 | uart->bugs = up->bugs; |
3263 | uart->port.mapbase = up->port.mapbase; | 3223 | uart->port.mapbase = up->port.mapbase; |
3264 | uart->port.private_data = up->port.private_data; | 3224 | uart->port.private_data = up->port.private_data; |
3225 | uart->port.fifosize = up->port.fifosize; | ||
3226 | uart->tx_loadsz = up->tx_loadsz; | ||
3227 | uart->capabilities = up->capabilities; | ||
3228 | |||
3265 | if (up->port.dev) | 3229 | if (up->port.dev) |
3266 | uart->port.dev = up->port.dev; | 3230 | uart->port.dev = up->port.dev; |
3267 | 3231 | ||
@@ -3287,6 +3251,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3287 | uart->dl_read = up->dl_read; | 3251 | uart->dl_read = up->dl_read; |
3288 | if (up->dl_write) | 3252 | if (up->dl_write) |
3289 | uart->dl_write = up->dl_write; | 3253 | uart->dl_write = up->dl_write; |
3254 | if (up->dma) | ||
3255 | uart->dma = up->dma; | ||
3290 | 3256 | ||
3291 | if (serial8250_isa_config != NULL) | 3257 | if (serial8250_isa_config != NULL) |
3292 | serial8250_isa_config(0, &uart->port, | 3258 | serial8250_isa_config(0, &uart->port, |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 12caa1292b75..34eb676916fe 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -12,6 +12,35 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
15 | #include <linux/dmaengine.h> | ||
16 | |||
17 | struct uart_8250_dma { | ||
18 | dma_filter_fn fn; | ||
19 | void *rx_param; | ||
20 | void *tx_param; | ||
21 | |||
22 | int rx_chan_id; | ||
23 | int tx_chan_id; | ||
24 | |||
25 | struct dma_slave_config rxconf; | ||
26 | struct dma_slave_config txconf; | ||
27 | |||
28 | struct dma_chan *rxchan; | ||
29 | struct dma_chan *txchan; | ||
30 | |||
31 | dma_addr_t rx_addr; | ||
32 | dma_addr_t tx_addr; | ||
33 | |||
34 | dma_cookie_t rx_cookie; | ||
35 | dma_cookie_t tx_cookie; | ||
36 | |||
37 | void *rx_buf; | ||
38 | |||
39 | size_t rx_size; | ||
40 | size_t tx_size; | ||
41 | |||
42 | unsigned char tx_running:1; | ||
43 | }; | ||
15 | 44 | ||
16 | struct old_serial_port { | 45 | struct old_serial_port { |
17 | unsigned int uart; | 46 | unsigned int uart; |
@@ -143,3 +172,24 @@ static inline int is_omap1510_8250(struct uart_8250_port *pt) | |||
143 | return 0; | 172 | return 0; |
144 | } | 173 | } |
145 | #endif | 174 | #endif |
175 | |||
176 | #ifdef CONFIG_SERIAL_8250_DMA | ||
177 | extern int serial8250_tx_dma(struct uart_8250_port *); | ||
178 | extern int serial8250_rx_dma(struct uart_8250_port *, unsigned int iir); | ||
179 | extern int serial8250_request_dma(struct uart_8250_port *); | ||
180 | extern void serial8250_release_dma(struct uart_8250_port *); | ||
181 | #else | ||
182 | static inline int serial8250_tx_dma(struct uart_8250_port *p) | ||
183 | { | ||
184 | return -1; | ||
185 | } | ||
186 | static inline int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | ||
187 | { | ||
188 | return -1; | ||
189 | } | ||
190 | static inline int serial8250_request_dma(struct uart_8250_port *p) | ||
191 | { | ||
192 | return -1; | ||
193 | } | ||
194 | static inline void serial8250_release_dma(struct uart_8250_port *p) { } | ||
195 | #endif | ||
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c new file mode 100644 index 000000000000..b9f7fd28112e --- /dev/null +++ b/drivers/tty/serial/8250/8250_dma.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * 8250_dma.c - DMA Engine API support for 8250.c | ||
3 | * | ||
4 | * Copyright (C) 2013 Intel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/tty.h> | ||
12 | #include <linux/tty_flip.h> | ||
13 | #include <linux/serial_reg.h> | ||
14 | #include <linux/dma-mapping.h> | ||
15 | |||
16 | #include "8250.h" | ||
17 | |||
18 | static void __dma_tx_complete(void *param) | ||
19 | { | ||
20 | struct uart_8250_port *p = param; | ||
21 | struct uart_8250_dma *dma = p->dma; | ||
22 | struct circ_buf *xmit = &p->port.state->xmit; | ||
23 | |||
24 | dma->tx_running = 0; | ||
25 | |||
26 | dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, | ||
27 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
28 | |||
29 | xmit->tail += dma->tx_size; | ||
30 | xmit->tail &= UART_XMIT_SIZE - 1; | ||
31 | p->port.icount.tx += dma->tx_size; | ||
32 | |||
33 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
34 | uart_write_wakeup(&p->port); | ||
35 | |||
36 | if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) { | ||
37 | serial8250_tx_dma(p); | ||
38 | uart_write_wakeup(&p->port); | ||
39 | } | ||
40 | } | ||
41 | |||
42 | static void __dma_rx_complete(void *param) | ||
43 | { | ||
44 | struct uart_8250_port *p = param; | ||
45 | struct uart_8250_dma *dma = p->dma; | ||
46 | struct tty_port *tty_port = &p->port.state->port; | ||
47 | struct dma_tx_state state; | ||
48 | int count; | ||
49 | |||
50 | dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr, | ||
51 | dma->rx_size, DMA_FROM_DEVICE); | ||
52 | |||
53 | dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); | ||
54 | dmaengine_terminate_all(dma->rxchan); | ||
55 | |||
56 | count = dma->rx_size - state.residue; | ||
57 | |||
58 | tty_insert_flip_string(tty_port, dma->rx_buf, count); | ||
59 | p->port.icount.rx += count; | ||
60 | |||
61 | tty_flip_buffer_push(tty_port); | ||
62 | } | ||
63 | |||
64 | int serial8250_tx_dma(struct uart_8250_port *p) | ||
65 | { | ||
66 | struct uart_8250_dma *dma = p->dma; | ||
67 | struct circ_buf *xmit = &p->port.state->xmit; | ||
68 | struct dma_async_tx_descriptor *desc; | ||
69 | |||
70 | if (dma->tx_running) | ||
71 | return -EBUSY; | ||
72 | |||
73 | dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
74 | if (!dma->tx_size) | ||
75 | return -EINVAL; | ||
76 | |||
77 | desc = dmaengine_prep_slave_single(dma->txchan, | ||
78 | dma->tx_addr + xmit->tail, | ||
79 | dma->tx_size, DMA_MEM_TO_DEV, | ||
80 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
81 | if (!desc) | ||
82 | return -EBUSY; | ||
83 | |||
84 | dma->tx_running = 1; | ||
85 | |||
86 | desc->callback = __dma_tx_complete; | ||
87 | desc->callback_param = p; | ||
88 | |||
89 | dma->tx_cookie = dmaengine_submit(desc); | ||
90 | |||
91 | dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr, | ||
92 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
93 | |||
94 | dma_async_issue_pending(dma->txchan); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | EXPORT_SYMBOL_GPL(serial8250_tx_dma); | ||
99 | |||
100 | int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) | ||
101 | { | ||
102 | struct uart_8250_dma *dma = p->dma; | ||
103 | struct dma_async_tx_descriptor *desc; | ||
104 | struct dma_tx_state state; | ||
105 | int dma_status; | ||
106 | |||
107 | /* | ||
108 | * If RCVR FIFO trigger level was not reached, complete the transfer and | ||
109 | * let 8250.c copy the remaining data. | ||
110 | */ | ||
111 | if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) { | ||
112 | dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, | ||
113 | &state); | ||
114 | if (dma_status == DMA_IN_PROGRESS) { | ||
115 | dmaengine_pause(dma->rxchan); | ||
116 | __dma_rx_complete(p); | ||
117 | } | ||
118 | return -ETIMEDOUT; | ||
119 | } | ||
120 | |||
121 | desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, | ||
122 | dma->rx_size, DMA_DEV_TO_MEM, | ||
123 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
124 | if (!desc) | ||
125 | return -EBUSY; | ||
126 | |||
127 | desc->callback = __dma_rx_complete; | ||
128 | desc->callback_param = p; | ||
129 | |||
130 | dma->rx_cookie = dmaengine_submit(desc); | ||
131 | |||
132 | dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr, | ||
133 | dma->rx_size, DMA_FROM_DEVICE); | ||
134 | |||
135 | dma_async_issue_pending(dma->rxchan); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(serial8250_rx_dma); | ||
140 | |||
141 | int serial8250_request_dma(struct uart_8250_port *p) | ||
142 | { | ||
143 | struct uart_8250_dma *dma = p->dma; | ||
144 | dma_cap_mask_t mask; | ||
145 | |||
146 | dma->rxconf.src_addr = p->port.mapbase + UART_RX; | ||
147 | dma->txconf.dst_addr = p->port.mapbase + UART_TX; | ||
148 | |||
149 | dma_cap_zero(mask); | ||
150 | dma_cap_set(DMA_SLAVE, mask); | ||
151 | |||
152 | /* Get a channel for RX */ | ||
153 | dma->rxchan = dma_request_channel(mask, dma->fn, dma->rx_param); | ||
154 | if (!dma->rxchan) | ||
155 | return -ENODEV; | ||
156 | |||
157 | dmaengine_slave_config(dma->rxchan, &dma->rxconf); | ||
158 | |||
159 | /* Get a channel for TX */ | ||
160 | dma->txchan = dma_request_channel(mask, dma->fn, dma->tx_param); | ||
161 | if (!dma->txchan) { | ||
162 | dma_release_channel(dma->rxchan); | ||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
166 | dmaengine_slave_config(dma->txchan, &dma->txconf); | ||
167 | |||
168 | /* RX buffer */ | ||
169 | if (!dma->rx_size) | ||
170 | dma->rx_size = PAGE_SIZE; | ||
171 | |||
172 | dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size, | ||
173 | &dma->rx_addr, GFP_KERNEL); | ||
174 | if (!dma->rx_buf) { | ||
175 | dma_release_channel(dma->rxchan); | ||
176 | dma_release_channel(dma->txchan); | ||
177 | return -ENOMEM; | ||
178 | } | ||
179 | |||
180 | /* TX buffer */ | ||
181 | dma->tx_addr = dma_map_single(dma->txchan->device->dev, | ||
182 | p->port.state->xmit.buf, | ||
183 | UART_XMIT_SIZE, | ||
184 | DMA_TO_DEVICE); | ||
185 | |||
186 | dev_dbg_ratelimited(p->port.dev, "got both dma channels\n"); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | EXPORT_SYMBOL_GPL(serial8250_request_dma); | ||
191 | |||
192 | void serial8250_release_dma(struct uart_8250_port *p) | ||
193 | { | ||
194 | struct uart_8250_dma *dma = p->dma; | ||
195 | |||
196 | if (!dma) | ||
197 | return; | ||
198 | |||
199 | /* Release RX resources */ | ||
200 | dmaengine_terminate_all(dma->rxchan); | ||
201 | dma_free_coherent(dma->rxchan->device->dev, dma->rx_size, dma->rx_buf, | ||
202 | dma->rx_addr); | ||
203 | dma_release_channel(dma->rxchan); | ||
204 | dma->rxchan = NULL; | ||
205 | |||
206 | /* Release TX resources */ | ||
207 | dmaengine_terminate_all(dma->txchan); | ||
208 | dma_unmap_single(dma->txchan->device->dev, dma->tx_addr, | ||
209 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
210 | dma_release_channel(dma->txchan); | ||
211 | dma->txchan = NULL; | ||
212 | dma->tx_running = 0; | ||
213 | |||
214 | dev_dbg_ratelimited(p->port.dev, "dma channels released\n"); | ||
215 | } | ||
216 | EXPORT_SYMBOL_GPL(serial8250_release_dma); | ||
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 096d2ef48b32..db0e66f6dd0e 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Synopsys DesignWare 8250 driver. | 2 | * Synopsys DesignWare 8250 driver. |
3 | * | 3 | * |
4 | * Copyright 2011 Picochip, Jamie Iles. | 4 | * Copyright 2011 Picochip, Jamie Iles. |
5 | * Copyright 2013 Intel Corporation | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -24,6 +25,34 @@ | |||
24 | #include <linux/of_platform.h> | 25 | #include <linux/of_platform.h> |
25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/acpi.h> | ||
29 | |||
30 | #include "8250.h" | ||
31 | |||
32 | /* Offsets for the DesignWare specific registers */ | ||
33 | #define DW_UART_USR 0x1f /* UART Status Register */ | ||
34 | #define DW_UART_CPR 0xf4 /* Component Parameter Register */ | ||
35 | #define DW_UART_UCV 0xf8 /* UART Component Version */ | ||
36 | |||
37 | /* Intel Low Power Subsystem specific */ | ||
38 | #define LPSS_PRV_CLOCK_PARAMS 0x800 | ||
39 | |||
40 | /* Component Parameter Register bits */ | ||
41 | #define DW_UART_CPR_ABP_DATA_WIDTH (3 << 0) | ||
42 | #define DW_UART_CPR_AFCE_MODE (1 << 4) | ||
43 | #define DW_UART_CPR_THRE_MODE (1 << 5) | ||
44 | #define DW_UART_CPR_SIR_MODE (1 << 6) | ||
45 | #define DW_UART_CPR_SIR_LP_MODE (1 << 7) | ||
46 | #define DW_UART_CPR_ADDITIONAL_FEATURES (1 << 8) | ||
47 | #define DW_UART_CPR_FIFO_ACCESS (1 << 9) | ||
48 | #define DW_UART_CPR_FIFO_STAT (1 << 10) | ||
49 | #define DW_UART_CPR_SHADOW (1 << 11) | ||
50 | #define DW_UART_CPR_ENCODED_PARMS (1 << 12) | ||
51 | #define DW_UART_CPR_DMA_EXTRA (1 << 13) | ||
52 | #define DW_UART_CPR_FIFO_MODE (0xff << 16) | ||
53 | /* Helper for fifo size calculation */ | ||
54 | #define DW_UART_CPR_FIFO_SIZE(a) (((a >> 16) & 0xff) * 16) | ||
55 | |||
27 | 56 | ||
28 | struct dw8250_data { | 57 | struct dw8250_data { |
29 | int last_lcr; | 58 | int last_lcr; |
@@ -66,9 +95,6 @@ static unsigned int dw8250_serial_in32(struct uart_port *p, int offset) | |||
66 | return readl(p->membase + offset); | 95 | return readl(p->membase + offset); |
67 | } | 96 | } |
68 | 97 | ||
69 | /* Offset for the DesignWare's UART Status Register. */ | ||
70 | #define UART_USR 0x1f | ||
71 | |||
72 | static int dw8250_handle_irq(struct uart_port *p) | 98 | static int dw8250_handle_irq(struct uart_port *p) |
73 | { | 99 | { |
74 | struct dw8250_data *d = p->private_data; | 100 | struct dw8250_data *d = p->private_data; |
@@ -78,7 +104,7 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
78 | return 1; | 104 | return 1; |
79 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { | 105 | } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) { |
80 | /* Clear the USR and write the LCR again. */ | 106 | /* Clear the USR and write the LCR again. */ |
81 | (void)p->serial_in(p, UART_USR); | 107 | (void)p->serial_in(p, DW_UART_USR); |
82 | p->serial_out(p, UART_LCR, d->last_lcr); | 108 | p->serial_out(p, UART_LCR, d->last_lcr); |
83 | 109 | ||
84 | return 1; | 110 | return 1; |
@@ -87,61 +113,210 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
87 | return 0; | 113 | return 0; |
88 | } | 114 | } |
89 | 115 | ||
116 | static int dw8250_probe_of(struct uart_port *p) | ||
117 | { | ||
118 | struct device_node *np = p->dev->of_node; | ||
119 | u32 val; | ||
120 | |||
121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | ||
122 | switch (val) { | ||
123 | case 1: | ||
124 | break; | ||
125 | case 4: | ||
126 | p->iotype = UPIO_MEM32; | ||
127 | p->serial_in = dw8250_serial_in32; | ||
128 | p->serial_out = dw8250_serial_out32; | ||
129 | break; | ||
130 | default: | ||
131 | dev_err(p->dev, "unsupported reg-io-width (%u)\n", val); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | if (!of_property_read_u32(np, "reg-shift", &val)) | ||
137 | p->regshift = val; | ||
138 | |||
139 | if (of_property_read_u32(np, "clock-frequency", &val)) { | ||
140 | dev_err(p->dev, "no clock-frequency property set\n"); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | p->uartclk = val; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | #ifdef CONFIG_ACPI | ||
149 | static bool dw8250_acpi_dma_filter(struct dma_chan *chan, void *parm) | ||
150 | { | ||
151 | return chan->chan_id == *(int *)parm; | ||
152 | } | ||
153 | |||
154 | static acpi_status | ||
155 | dw8250_acpi_walk_resource(struct acpi_resource *res, void *data) | ||
156 | { | ||
157 | struct uart_port *p = data; | ||
158 | struct uart_8250_port *port; | ||
159 | struct uart_8250_dma *dma; | ||
160 | struct acpi_resource_fixed_dma *fixed_dma; | ||
161 | struct dma_slave_config *slave; | ||
162 | |||
163 | port = container_of(p, struct uart_8250_port, port); | ||
164 | |||
165 | switch (res->type) { | ||
166 | case ACPI_RESOURCE_TYPE_FIXED_DMA: | ||
167 | fixed_dma = &res->data.fixed_dma; | ||
168 | |||
169 | /* TX comes first */ | ||
170 | if (!port->dma) { | ||
171 | dma = devm_kzalloc(p->dev, sizeof(*dma), GFP_KERNEL); | ||
172 | if (!dma) | ||
173 | return AE_NO_MEMORY; | ||
174 | |||
175 | port->dma = dma; | ||
176 | slave = &dma->txconf; | ||
177 | |||
178 | slave->direction = DMA_MEM_TO_DEV; | ||
179 | slave->dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
180 | slave->slave_id = fixed_dma->request_lines; | ||
181 | slave->dst_maxburst = port->tx_loadsz / 4; | ||
182 | |||
183 | dma->tx_chan_id = fixed_dma->channels; | ||
184 | dma->tx_param = &dma->tx_chan_id; | ||
185 | dma->fn = dw8250_acpi_dma_filter; | ||
186 | } else { | ||
187 | dma = port->dma; | ||
188 | slave = &dma->rxconf; | ||
189 | |||
190 | slave->direction = DMA_DEV_TO_MEM; | ||
191 | slave->src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
192 | slave->slave_id = fixed_dma->request_lines; | ||
193 | slave->src_maxburst = p->fifosize / 4; | ||
194 | |||
195 | dma->rx_chan_id = fixed_dma->channels; | ||
196 | dma->rx_param = &dma->rx_chan_id; | ||
197 | } | ||
198 | |||
199 | break; | ||
200 | } | ||
201 | |||
202 | return AE_OK; | ||
203 | } | ||
204 | |||
205 | static int dw8250_probe_acpi(struct uart_port *p) | ||
206 | { | ||
207 | const struct acpi_device_id *id; | ||
208 | acpi_status status; | ||
209 | u32 reg; | ||
210 | |||
211 | id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev); | ||
212 | if (!id) | ||
213 | return -ENODEV; | ||
214 | |||
215 | p->iotype = UPIO_MEM32; | ||
216 | p->serial_in = dw8250_serial_in32; | ||
217 | p->serial_out = dw8250_serial_out32; | ||
218 | p->regshift = 2; | ||
219 | p->uartclk = (unsigned int)id->driver_data; | ||
220 | |||
221 | status = acpi_walk_resources(ACPI_HANDLE(p->dev), METHOD_NAME__CRS, | ||
222 | dw8250_acpi_walk_resource, p); | ||
223 | if (ACPI_FAILURE(status)) { | ||
224 | dev_err_ratelimited(p->dev, "%s failed \"%s\"\n", __func__, | ||
225 | acpi_format_exception(status)); | ||
226 | return -ENODEV; | ||
227 | } | ||
228 | |||
229 | /* Fix Haswell issue where the clocks do not get enabled */ | ||
230 | if (!strcmp(id->id, "INT33C4") || !strcmp(id->id, "INT33C5")) { | ||
231 | reg = readl(p->membase + LPSS_PRV_CLOCK_PARAMS); | ||
232 | writel(reg | 1, p->membase + LPSS_PRV_CLOCK_PARAMS); | ||
233 | } | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | #else | ||
238 | static inline int dw8250_probe_acpi(struct uart_port *p) | ||
239 | { | ||
240 | return -ENODEV; | ||
241 | } | ||
242 | #endif /* CONFIG_ACPI */ | ||
243 | |||
244 | static void dw8250_setup_port(struct uart_8250_port *up) | ||
245 | { | ||
246 | struct uart_port *p = &up->port; | ||
247 | u32 reg = readl(p->membase + DW_UART_UCV); | ||
248 | |||
249 | /* | ||
250 | * If the Component Version Register returns zero, we know that | ||
251 | * ADDITIONAL_FEATURES are not enabled. No need to go any further. | ||
252 | */ | ||
253 | if (!reg) | ||
254 | return; | ||
255 | |||
256 | dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n", | ||
257 | (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); | ||
258 | |||
259 | reg = readl(p->membase + DW_UART_CPR); | ||
260 | if (!reg) | ||
261 | return; | ||
262 | |||
263 | /* Select the type based on fifo */ | ||
264 | if (reg & DW_UART_CPR_FIFO_MODE) { | ||
265 | p->type = PORT_16550A; | ||
266 | p->flags |= UPF_FIXED_TYPE; | ||
267 | p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); | ||
268 | up->tx_loadsz = p->fifosize; | ||
269 | } | ||
270 | } | ||
271 | |||
90 | static int dw8250_probe(struct platform_device *pdev) | 272 | static int dw8250_probe(struct platform_device *pdev) |
91 | { | 273 | { |
92 | struct uart_8250_port uart = {}; | 274 | struct uart_8250_port uart = {}; |
93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 275 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
94 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 276 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
95 | struct device_node *np = pdev->dev.of_node; | ||
96 | u32 val; | ||
97 | struct dw8250_data *data; | 277 | struct dw8250_data *data; |
278 | int err; | ||
98 | 279 | ||
99 | if (!regs || !irq) { | 280 | if (!regs || !irq) { |
100 | dev_err(&pdev->dev, "no registers/irq defined\n"); | 281 | dev_err(&pdev->dev, "no registers/irq defined\n"); |
101 | return -EINVAL; | 282 | return -EINVAL; |
102 | } | 283 | } |
103 | 284 | ||
104 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
105 | if (!data) | ||
106 | return -ENOMEM; | ||
107 | uart.port.private_data = data; | ||
108 | |||
109 | spin_lock_init(&uart.port.lock); | 285 | spin_lock_init(&uart.port.lock); |
110 | uart.port.mapbase = regs->start; | 286 | uart.port.mapbase = regs->start; |
111 | uart.port.irq = irq->start; | 287 | uart.port.irq = irq->start; |
112 | uart.port.handle_irq = dw8250_handle_irq; | 288 | uart.port.handle_irq = dw8250_handle_irq; |
113 | uart.port.type = PORT_8250; | 289 | uart.port.type = PORT_8250; |
114 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | | 290 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; |
115 | UPF_FIXED_PORT | UPF_FIXED_TYPE; | ||
116 | uart.port.dev = &pdev->dev; | 291 | uart.port.dev = &pdev->dev; |
117 | 292 | ||
293 | uart.port.membase = ioremap(regs->start, resource_size(regs)); | ||
294 | if (!uart.port.membase) | ||
295 | return -ENOMEM; | ||
296 | |||
118 | uart.port.iotype = UPIO_MEM; | 297 | uart.port.iotype = UPIO_MEM; |
119 | uart.port.serial_in = dw8250_serial_in; | 298 | uart.port.serial_in = dw8250_serial_in; |
120 | uart.port.serial_out = dw8250_serial_out; | 299 | uart.port.serial_out = dw8250_serial_out; |
121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | 300 | |
122 | switch (val) { | 301 | dw8250_setup_port(&uart); |
123 | case 1: | 302 | |
124 | break; | 303 | if (pdev->dev.of_node) { |
125 | case 4: | 304 | err = dw8250_probe_of(&uart.port); |
126 | uart.port.iotype = UPIO_MEM32; | 305 | if (err) |
127 | uart.port.serial_in = dw8250_serial_in32; | 306 | return err; |
128 | uart.port.serial_out = dw8250_serial_out32; | 307 | } else if (ACPI_HANDLE(&pdev->dev)) { |
129 | break; | 308 | err = dw8250_probe_acpi(&uart.port); |
130 | default: | 309 | if (err) |
131 | dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n", | 310 | return err; |
132 | val); | 311 | } else { |
133 | return -EINVAL; | 312 | return -ENODEV; |
134 | } | ||
135 | } | 313 | } |
136 | 314 | ||
137 | if (!of_property_read_u32(np, "reg-shift", &val)) | 315 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
138 | uart.port.regshift = val; | 316 | if (!data) |
317 | return -ENOMEM; | ||
139 | 318 | ||
140 | if (of_property_read_u32(np, "clock-frequency", &val)) { | 319 | uart.port.private_data = data; |
141 | dev_err(&pdev->dev, "no clock-frequency property set\n"); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | uart.port.uartclk = val; | ||
145 | 320 | ||
146 | data->line = serial8250_register_8250_port(&uart); | 321 | data->line = serial8250_register_8250_port(&uart); |
147 | if (data->line < 0) | 322 | if (data->line < 0) |
@@ -184,17 +359,25 @@ static int dw8250_resume(struct platform_device *pdev) | |||
184 | #define dw8250_resume NULL | 359 | #define dw8250_resume NULL |
185 | #endif /* CONFIG_PM */ | 360 | #endif /* CONFIG_PM */ |
186 | 361 | ||
187 | static const struct of_device_id dw8250_match[] = { | 362 | static const struct of_device_id dw8250_of_match[] = { |
188 | { .compatible = "snps,dw-apb-uart" }, | 363 | { .compatible = "snps,dw-apb-uart" }, |
189 | { /* Sentinel */ } | 364 | { /* Sentinel */ } |
190 | }; | 365 | }; |
191 | MODULE_DEVICE_TABLE(of, dw8250_match); | 366 | MODULE_DEVICE_TABLE(of, dw8250_of_match); |
367 | |||
368 | static const struct acpi_device_id dw8250_acpi_match[] = { | ||
369 | { "INT33C4", 100000000 }, | ||
370 | { "INT33C5", 100000000 }, | ||
371 | { }, | ||
372 | }; | ||
373 | MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match); | ||
192 | 374 | ||
193 | static struct platform_driver dw8250_platform_driver = { | 375 | static struct platform_driver dw8250_platform_driver = { |
194 | .driver = { | 376 | .driver = { |
195 | .name = "dw-apb-uart", | 377 | .name = "dw-apb-uart", |
196 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
197 | .of_match_table = dw8250_match, | 379 | .of_match_table = dw8250_of_match, |
380 | .acpi_match_table = ACPI_PTR(dw8250_acpi_match), | ||
198 | }, | 381 | }, |
199 | .probe = dw8250_probe, | 382 | .probe = dw8250_probe, |
200 | .remove = dw8250_remove, | 383 | .remove = dw8250_remove, |
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index f53a7db4350d..721904f8efa9 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c | |||
@@ -194,7 +194,7 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
194 | options++; | 194 | options++; |
195 | device->baud = simple_strtoul(options, NULL, 0); | 195 | device->baud = simple_strtoul(options, NULL, 0); |
196 | length = min(strcspn(options, " "), sizeof(device->options)); | 196 | length = min(strcspn(options, " "), sizeof(device->options)); |
197 | strncpy(device->options, options, length); | 197 | strlcpy(device->options, options, length); |
198 | } else { | 198 | } else { |
199 | device->baud = probe_baud(port); | 199 | device->baud = probe_baud(port); |
200 | snprintf(device->options, sizeof(device->options), "%u", | 200 | snprintf(device->options, sizeof(device->options), "%u", |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index a27a98e1b066..791c5a77ec61 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1040,6 +1040,253 @@ static int pci_asix_setup(struct serial_private *priv, | |||
1040 | return pci_default_setup(priv, board, port, idx); | 1040 | return pci_default_setup(priv, board, port, idx); |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | /* Quatech devices have their own extra interface features */ | ||
1044 | |||
1045 | struct quatech_feature { | ||
1046 | u16 devid; | ||
1047 | bool amcc; | ||
1048 | }; | ||
1049 | |||
1050 | #define QPCR_TEST_FOR1 0x3F | ||
1051 | #define QPCR_TEST_GET1 0x00 | ||
1052 | #define QPCR_TEST_FOR2 0x40 | ||
1053 | #define QPCR_TEST_GET2 0x40 | ||
1054 | #define QPCR_TEST_FOR3 0x80 | ||
1055 | #define QPCR_TEST_GET3 0x40 | ||
1056 | #define QPCR_TEST_FOR4 0xC0 | ||
1057 | #define QPCR_TEST_GET4 0x80 | ||
1058 | |||
1059 | #define QOPR_CLOCK_X1 0x0000 | ||
1060 | #define QOPR_CLOCK_X2 0x0001 | ||
1061 | #define QOPR_CLOCK_X4 0x0002 | ||
1062 | #define QOPR_CLOCK_X8 0x0003 | ||
1063 | #define QOPR_CLOCK_RATE_MASK 0x0003 | ||
1064 | |||
1065 | |||
1066 | static struct quatech_feature quatech_cards[] = { | ||
1067 | { PCI_DEVICE_ID_QUATECH_QSC100, 1 }, | ||
1068 | { PCI_DEVICE_ID_QUATECH_DSC100, 1 }, | ||
1069 | { PCI_DEVICE_ID_QUATECH_DSC100E, 0 }, | ||
1070 | { PCI_DEVICE_ID_QUATECH_DSC200, 1 }, | ||
1071 | { PCI_DEVICE_ID_QUATECH_DSC200E, 0 }, | ||
1072 | { PCI_DEVICE_ID_QUATECH_ESC100D, 1 }, | ||
1073 | { PCI_DEVICE_ID_QUATECH_ESC100M, 1 }, | ||
1074 | { PCI_DEVICE_ID_QUATECH_QSCP100, 1 }, | ||
1075 | { PCI_DEVICE_ID_QUATECH_DSCP100, 1 }, | ||
1076 | { PCI_DEVICE_ID_QUATECH_QSCP200, 1 }, | ||
1077 | { PCI_DEVICE_ID_QUATECH_DSCP200, 1 }, | ||
1078 | { PCI_DEVICE_ID_QUATECH_ESCLP100, 0 }, | ||
1079 | { PCI_DEVICE_ID_QUATECH_QSCLP100, 0 }, | ||
1080 | { PCI_DEVICE_ID_QUATECH_DSCLP100, 0 }, | ||
1081 | { PCI_DEVICE_ID_QUATECH_SSCLP100, 0 }, | ||
1082 | { PCI_DEVICE_ID_QUATECH_QSCLP200, 0 }, | ||
1083 | { PCI_DEVICE_ID_QUATECH_DSCLP200, 0 }, | ||
1084 | { PCI_DEVICE_ID_QUATECH_SSCLP200, 0 }, | ||
1085 | { PCI_DEVICE_ID_QUATECH_SPPXP_100, 0 }, | ||
1086 | { 0, } | ||
1087 | }; | ||
1088 | |||
1089 | static int pci_quatech_amcc(u16 devid) | ||
1090 | { | ||
1091 | struct quatech_feature *qf = &quatech_cards[0]; | ||
1092 | while (qf->devid) { | ||
1093 | if (qf->devid == devid) | ||
1094 | return qf->amcc; | ||
1095 | qf++; | ||
1096 | } | ||
1097 | pr_err("quatech: unknown port type '0x%04X'.\n", devid); | ||
1098 | return 0; | ||
1099 | }; | ||
1100 | |||
1101 | static int pci_quatech_rqopr(struct uart_8250_port *port) | ||
1102 | { | ||
1103 | unsigned long base = port->port.iobase; | ||
1104 | u8 LCR, val; | ||
1105 | |||
1106 | LCR = inb(base + UART_LCR); | ||
1107 | outb(0xBF, base + UART_LCR); | ||
1108 | val = inb(base + UART_SCR); | ||
1109 | outb(LCR, base + UART_LCR); | ||
1110 | return val; | ||
1111 | } | ||
1112 | |||
1113 | static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr) | ||
1114 | { | ||
1115 | unsigned long base = port->port.iobase; | ||
1116 | u8 LCR, val; | ||
1117 | |||
1118 | LCR = inb(base + UART_LCR); | ||
1119 | outb(0xBF, base + UART_LCR); | ||
1120 | val = inb(base + UART_SCR); | ||
1121 | outb(qopr, base + UART_SCR); | ||
1122 | outb(LCR, base + UART_LCR); | ||
1123 | } | ||
1124 | |||
1125 | static int pci_quatech_rqmcr(struct uart_8250_port *port) | ||
1126 | { | ||
1127 | unsigned long base = port->port.iobase; | ||
1128 | u8 LCR, val, qmcr; | ||
1129 | |||
1130 | LCR = inb(base + UART_LCR); | ||
1131 | outb(0xBF, base + UART_LCR); | ||
1132 | val = inb(base + UART_SCR); | ||
1133 | outb(val | 0x10, base + UART_SCR); | ||
1134 | qmcr = inb(base + UART_MCR); | ||
1135 | outb(val, base + UART_SCR); | ||
1136 | outb(LCR, base + UART_LCR); | ||
1137 | |||
1138 | return qmcr; | ||
1139 | } | ||
1140 | |||
1141 | static void pci_quatech_wqmcr(struct uart_8250_port *port, u8 qmcr) | ||
1142 | { | ||
1143 | unsigned long base = port->port.iobase; | ||
1144 | u8 LCR, val; | ||
1145 | |||
1146 | LCR = inb(base + UART_LCR); | ||
1147 | outb(0xBF, base + UART_LCR); | ||
1148 | val = inb(base + UART_SCR); | ||
1149 | outb(val | 0x10, base + UART_SCR); | ||
1150 | outb(qmcr, base + UART_MCR); | ||
1151 | outb(val, base + UART_SCR); | ||
1152 | outb(LCR, base + UART_LCR); | ||
1153 | } | ||
1154 | |||
1155 | static int pci_quatech_has_qmcr(struct uart_8250_port *port) | ||
1156 | { | ||
1157 | unsigned long base = port->port.iobase; | ||
1158 | u8 LCR, val; | ||
1159 | |||
1160 | LCR = inb(base + UART_LCR); | ||
1161 | outb(0xBF, base + UART_LCR); | ||
1162 | val = inb(base + UART_SCR); | ||
1163 | if (val & 0x20) { | ||
1164 | outb(0x80, UART_LCR); | ||
1165 | if (!(inb(UART_SCR) & 0x20)) { | ||
1166 | outb(LCR, base + UART_LCR); | ||
1167 | return 1; | ||
1168 | } | ||
1169 | } | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static int pci_quatech_test(struct uart_8250_port *port) | ||
1174 | { | ||
1175 | u8 reg; | ||
1176 | u8 qopr = pci_quatech_rqopr(port); | ||
1177 | pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1); | ||
1178 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1179 | if (reg != QPCR_TEST_GET1) | ||
1180 | return -EINVAL; | ||
1181 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR2); | ||
1182 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1183 | if (reg != QPCR_TEST_GET2) | ||
1184 | return -EINVAL; | ||
1185 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR3); | ||
1186 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1187 | if (reg != QPCR_TEST_GET3) | ||
1188 | return -EINVAL; | ||
1189 | pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR4); | ||
1190 | reg = pci_quatech_rqopr(port) & 0xC0; | ||
1191 | if (reg != QPCR_TEST_GET4) | ||
1192 | return -EINVAL; | ||
1193 | |||
1194 | pci_quatech_wqopr(port, qopr); | ||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | static int pci_quatech_clock(struct uart_8250_port *port) | ||
1199 | { | ||
1200 | u8 qopr, reg, set; | ||
1201 | unsigned long clock; | ||
1202 | |||
1203 | if (pci_quatech_test(port) < 0) | ||
1204 | return 1843200; | ||
1205 | |||
1206 | qopr = pci_quatech_rqopr(port); | ||
1207 | |||
1208 | pci_quatech_wqopr(port, qopr & ~QOPR_CLOCK_X8); | ||
1209 | reg = pci_quatech_rqopr(port); | ||
1210 | if (reg & QOPR_CLOCK_X8) { | ||
1211 | clock = 1843200; | ||
1212 | goto out; | ||
1213 | } | ||
1214 | pci_quatech_wqopr(port, qopr | QOPR_CLOCK_X8); | ||
1215 | reg = pci_quatech_rqopr(port); | ||
1216 | if (!(reg & QOPR_CLOCK_X8)) { | ||
1217 | clock = 1843200; | ||
1218 | goto out; | ||
1219 | } | ||
1220 | reg &= QOPR_CLOCK_X8; | ||
1221 | if (reg == QOPR_CLOCK_X2) { | ||
1222 | clock = 3685400; | ||
1223 | set = QOPR_CLOCK_X2; | ||
1224 | } else if (reg == QOPR_CLOCK_X4) { | ||
1225 | clock = 7372800; | ||
1226 | set = QOPR_CLOCK_X4; | ||
1227 | } else if (reg == QOPR_CLOCK_X8) { | ||
1228 | clock = 14745600; | ||
1229 | set = QOPR_CLOCK_X8; | ||
1230 | } else { | ||
1231 | clock = 1843200; | ||
1232 | set = QOPR_CLOCK_X1; | ||
1233 | } | ||
1234 | qopr &= ~QOPR_CLOCK_RATE_MASK; | ||
1235 | qopr |= set; | ||
1236 | |||
1237 | out: | ||
1238 | pci_quatech_wqopr(port, qopr); | ||
1239 | return clock; | ||
1240 | } | ||
1241 | |||
1242 | static int pci_quatech_rs422(struct uart_8250_port *port) | ||
1243 | { | ||
1244 | u8 qmcr; | ||
1245 | int rs422 = 0; | ||
1246 | |||
1247 | if (!pci_quatech_has_qmcr(port)) | ||
1248 | return 0; | ||
1249 | qmcr = pci_quatech_rqmcr(port); | ||
1250 | pci_quatech_wqmcr(port, 0xFF); | ||
1251 | if (pci_quatech_rqmcr(port)) | ||
1252 | rs422 = 1; | ||
1253 | pci_quatech_wqmcr(port, qmcr); | ||
1254 | return rs422; | ||
1255 | } | ||
1256 | |||
1257 | static int pci_quatech_init(struct pci_dev *dev) | ||
1258 | { | ||
1259 | if (pci_quatech_amcc(dev->device)) { | ||
1260 | unsigned long base = pci_resource_start(dev, 0); | ||
1261 | if (base) { | ||
1262 | u32 tmp; | ||
1263 | outl(inl(base + 0x38), base + 0x38); | ||
1264 | tmp = inl(base + 0x3c); | ||
1265 | outl(tmp | 0x01000000, base + 0x3c); | ||
1266 | outl(tmp, base + 0x3c); | ||
1267 | } | ||
1268 | } | ||
1269 | return 0; | ||
1270 | } | ||
1271 | |||
1272 | static int pci_quatech_setup(struct serial_private *priv, | ||
1273 | const struct pciserial_board *board, | ||
1274 | struct uart_8250_port *port, int idx) | ||
1275 | { | ||
1276 | /* Needed by pci_quatech calls below */ | ||
1277 | port->port.iobase = pci_resource_start(priv->dev, FL_GET_BASE(board->flags)); | ||
1278 | /* Set up the clocking */ | ||
1279 | port->port.uartclk = pci_quatech_clock(port); | ||
1280 | /* For now just warn about RS422 */ | ||
1281 | if (pci_quatech_rs422(port)) | ||
1282 | pr_warn("quatech: software control of RS422 features not currently supported.\n"); | ||
1283 | return pci_default_setup(priv, board, port, idx); | ||
1284 | } | ||
1285 | |||
1286 | static void pci_quatech_exit(struct pci_dev *dev) | ||
1287 | { | ||
1288 | } | ||
1289 | |||
1043 | static int pci_default_setup(struct serial_private *priv, | 1290 | static int pci_default_setup(struct serial_private *priv, |
1044 | const struct pciserial_board *board, | 1291 | const struct pciserial_board *board, |
1045 | struct uart_8250_port *port, int idx) | 1292 | struct uart_8250_port *port, int idx) |
@@ -1318,6 +1565,9 @@ pci_wch_ch353_setup(struct serial_private *priv, | |||
1318 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 | 1565 | #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0022 |
1319 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a | 1566 | #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a |
1320 | 1567 | ||
1568 | #define PCI_VENDOR_ID_SUNIX 0x1fd4 | ||
1569 | #define PCI_DEVICE_ID_SUNIX_1999 0x1999 | ||
1570 | |||
1321 | 1571 | ||
1322 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1572 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1323 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1573 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -1541,6 +1791,16 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1541 | .setup = pci_ni8430_setup, | 1791 | .setup = pci_ni8430_setup, |
1542 | .exit = pci_ni8430_exit, | 1792 | .exit = pci_ni8430_exit, |
1543 | }, | 1793 | }, |
1794 | /* Quatech */ | ||
1795 | { | ||
1796 | .vendor = PCI_VENDOR_ID_QUATECH, | ||
1797 | .device = PCI_ANY_ID, | ||
1798 | .subvendor = PCI_ANY_ID, | ||
1799 | .subdevice = PCI_ANY_ID, | ||
1800 | .init = pci_quatech_init, | ||
1801 | .setup = pci_quatech_setup, | ||
1802 | .exit = pci_quatech_exit, | ||
1803 | }, | ||
1544 | /* | 1804 | /* |
1545 | * Panacom | 1805 | * Panacom |
1546 | */ | 1806 | */ |
@@ -1704,6 +1964,23 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1704 | .setup = pci_timedia_setup, | 1964 | .setup = pci_timedia_setup, |
1705 | }, | 1965 | }, |
1706 | /* | 1966 | /* |
1967 | * SUNIX (Timedia) cards | ||
1968 | * Do not "probe" for these cards as there is at least one combination | ||
1969 | * card that should be handled by parport_pc that doesn't match the | ||
1970 | * rule in pci_timedia_probe. | ||
1971 | * It is part number is MIO5079A but its subdevice ID is 0x0102. | ||
1972 | * There are some boards with part number SER5037AL that report | ||
1973 | * subdevice ID 0x0002. | ||
1974 | */ | ||
1975 | { | ||
1976 | .vendor = PCI_VENDOR_ID_SUNIX, | ||
1977 | .device = PCI_DEVICE_ID_SUNIX_1999, | ||
1978 | .subvendor = PCI_VENDOR_ID_SUNIX, | ||
1979 | .subdevice = PCI_ANY_ID, | ||
1980 | .init = pci_timedia_init, | ||
1981 | .setup = pci_timedia_setup, | ||
1982 | }, | ||
1983 | /* | ||
1707 | * Exar cards | 1984 | * Exar cards |
1708 | */ | 1985 | */ |
1709 | { | 1986 | { |
@@ -3506,18 +3783,70 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3506 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, | 3783 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS, |
3507 | 0x10b5, 0x106a, 0, 0, | 3784 | 0x10b5, 0x106a, 0, 0, |
3508 | pbn_plx_romulus }, | 3785 | pbn_plx_romulus }, |
3786 | /* | ||
3787 | * Quatech cards. These actually have configurable clocks but for | ||
3788 | * now we just use the default. | ||
3789 | * | ||
3790 | * 100 series are RS232, 200 series RS422, | ||
3791 | */ | ||
3509 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, | 3792 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100, |
3510 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3793 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3511 | pbn_b1_4_115200 }, | 3794 | pbn_b1_4_115200 }, |
3512 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100, | 3795 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100, |
3513 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3796 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3514 | pbn_b1_2_115200 }, | 3797 | pbn_b1_2_115200 }, |
3798 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100E, | ||
3799 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3800 | pbn_b2_2_115200 }, | ||
3801 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200, | ||
3802 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3803 | pbn_b1_2_115200 }, | ||
3804 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200E, | ||
3805 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3806 | pbn_b2_2_115200 }, | ||
3807 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC200, | ||
3808 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3809 | pbn_b1_4_115200 }, | ||
3515 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D, | 3810 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D, |
3516 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3811 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3517 | pbn_b1_8_115200 }, | 3812 | pbn_b1_8_115200 }, |
3518 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, | 3813 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M, |
3519 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 3814 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
3520 | pbn_b1_8_115200 }, | 3815 | pbn_b1_8_115200 }, |
3816 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP100, | ||
3817 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3818 | pbn_b1_4_115200 }, | ||
3819 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP100, | ||
3820 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3821 | pbn_b1_2_115200 }, | ||
3822 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP200, | ||
3823 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3824 | pbn_b1_4_115200 }, | ||
3825 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP200, | ||
3826 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3827 | pbn_b1_2_115200 }, | ||
3828 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP100, | ||
3829 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3830 | pbn_b2_4_115200 }, | ||
3831 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP100, | ||
3832 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3833 | pbn_b2_2_115200 }, | ||
3834 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP100, | ||
3835 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3836 | pbn_b2_1_115200 }, | ||
3837 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP200, | ||
3838 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3839 | pbn_b2_4_115200 }, | ||
3840 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP200, | ||
3841 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3842 | pbn_b2_2_115200 }, | ||
3843 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP200, | ||
3844 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3845 | pbn_b2_1_115200 }, | ||
3846 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESCLP100, | ||
3847 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
3848 | pbn_b0_8_115200 }, | ||
3849 | |||
3521 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, | 3850 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954, |
3522 | PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, | 3851 | PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, |
3523 | 0, 0, | 3852 | 0, 0, |
@@ -3902,6 +4231,19 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3902 | pbn_b0_bt_1_921600 }, | 4231 | pbn_b0_bt_1_921600 }, |
3903 | 4232 | ||
3904 | /* | 4233 | /* |
4234 | * SUNIX (TIMEDIA) | ||
4235 | */ | ||
4236 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, | ||
4237 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, | ||
4238 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, | ||
4239 | pbn_b0_bt_1_921600 }, | ||
4240 | |||
4241 | { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, | ||
4242 | PCI_VENDOR_ID_SUNIX, PCI_ANY_ID, | ||
4243 | PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, | ||
4244 | pbn_b0_bt_1_921600 }, | ||
4245 | |||
4246 | /* | ||
3905 | * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> | 4247 | * AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> |
3906 | */ | 4248 | */ |
3907 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, | 4249 | { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, |
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c31133a6ea8e..2ef9537bcb2c 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig | |||
@@ -84,6 +84,14 @@ config SERIAL_8250_GSC | |||
84 | depends on SERIAL_8250 && GSC | 84 | depends on SERIAL_8250 && GSC |
85 | default SERIAL_8250 | 85 | default SERIAL_8250 |
86 | 86 | ||
87 | config SERIAL_8250_DMA | ||
88 | bool "DMA support for 16550 compatible UART controllers" if EXPERT | ||
89 | depends on SERIAL_8250 && DMADEVICES=y | ||
90 | default SERIAL_8250 | ||
91 | help | ||
92 | This builds DMA support that can be used with 8250/16650 | ||
93 | compatible UART controllers that support DMA signaling. | ||
94 | |||
87 | config SERIAL_8250_PCI | 95 | config SERIAL_8250_PCI |
88 | tristate "8250/16550 PCI device support" if EXPERT | 96 | tristate "8250/16550 PCI device support" if EXPERT |
89 | depends on SERIAL_8250 && PCI | 97 | depends on SERIAL_8250 && PCI |
@@ -249,15 +257,6 @@ config SERIAL_8250_ACORN | |||
249 | system, say Y to this option. The driver can handle 1, 2, or 3 port | 257 | system, say Y to this option. The driver can handle 1, 2, or 3 port |
250 | cards. If unsure, say N. | 258 | cards. If unsure, say N. |
251 | 259 | ||
252 | config SERIAL_8250_RM9K | ||
253 | bool "Support for MIPS RM9xxx integrated serial port" | ||
254 | depends on SERIAL_8250 != n && SERIAL_RM9000 | ||
255 | select SERIAL_8250_SHARE_IRQ | ||
256 | help | ||
257 | Selecting this option will add support for the integrated serial | ||
258 | port hardware found on MIPS RM9122 and similar processors. | ||
259 | If unsure, say N. | ||
260 | |||
261 | config SERIAL_8250_FSL | 260 | config SERIAL_8250_FSL |
262 | bool | 261 | bool |
263 | depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 | 262 | depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 |
@@ -265,7 +264,7 @@ config SERIAL_8250_FSL | |||
265 | 264 | ||
266 | config SERIAL_8250_DW | 265 | config SERIAL_8250_DW |
267 | tristate "Support for Synopsys DesignWare 8250 quirks" | 266 | tristate "Support for Synopsys DesignWare 8250 quirks" |
268 | depends on SERIAL_8250 && OF | 267 | depends on SERIAL_8250 |
269 | help | 268 | help |
270 | Selecting this option will enable handling of the extra features | 269 | Selecting this option will enable handling of the extra features |
271 | present in the Synopsys DesignWare APB UART. | 270 | present in the Synopsys DesignWare APB UART. |
@@ -277,3 +276,11 @@ config SERIAL_8250_EM | |||
277 | Selecting this option will add support for the integrated serial | 276 | Selecting this option will add support for the integrated serial |
278 | port hardware found on the Emma Mobile line of processors. | 277 | port hardware found on the Emma Mobile line of processors. |
279 | If unsure, say N. | 278 | If unsure, say N. |
279 | |||
280 | config SERIAL_8250_RT288X | ||
281 | bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support" | ||
282 | depends on SERIAL_8250 && (SOC_RT288X || SOC_RT305X || SOC_RT3883) | ||
283 | help | ||
284 | If you have a Ralink RT288x/RT305x SoC based board and want to use the | ||
285 | serial port, say Y to this option. The driver can handle up to 2 serial | ||
286 | ports. If unsure, say N. | ||
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 108fe7fe13e2..a23838a4d535 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | obj-$(CONFIG_SERIAL_8250) += 8250_core.o | 5 | obj-$(CONFIG_SERIAL_8250) += 8250_core.o |
6 | 8250_core-y := 8250.o | 6 | 8250_core-y := 8250.o |
7 | 8250_core-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o | 7 | 8250_core-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o |
8 | 8250_core-$(CONFIG_SERIAL_8250_DMA) += 8250_dma.o | ||
8 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o | 9 | obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o |
9 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o | 10 | obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o |
10 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o | 11 | obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 59c23d038106..a0162cbf0557 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -2,8 +2,10 @@ | |||
2 | # Serial device configuration | 2 | # Serial device configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | if TTY | ||
6 | |||
5 | menu "Serial drivers" | 7 | menu "Serial drivers" |
6 | depends on HAS_IOMEM | 8 | depends on HAS_IOMEM && GENERIC_HARDIRQS |
7 | 9 | ||
8 | source "drivers/tty/serial/8250/Kconfig" | 10 | source "drivers/tty/serial/8250/Kconfig" |
9 | 11 | ||
@@ -269,6 +271,17 @@ config SERIAL_SIRFSOC_CONSOLE | |||
269 | your boot loader about how to pass options to the kernel at | 271 | your boot loader about how to pass options to the kernel at |
270 | boot time.) | 272 | boot time.) |
271 | 273 | ||
274 | config SERIAL_TEGRA | ||
275 | tristate "NVIDIA Tegra20/30 SoC serial controller" | ||
276 | depends on ARCH_TEGRA && TEGRA20_APB_DMA | ||
277 | select SERIAL_CORE | ||
278 | help | ||
279 | Support for the on-chip UARTs on the NVIDIA Tegra series SOCs | ||
280 | providing /dev/ttyHS0, 1, 2, 3 and 4 (note, some machines may not | ||
281 | provide all of these ports, depending on how the serial port | ||
282 | are enabled). This driver uses the APB DMA to achieve higher baudrate | ||
283 | and better performance. | ||
284 | |||
272 | config SERIAL_MAX3100 | 285 | config SERIAL_MAX3100 |
273 | tristate "MAX3100 support" | 286 | tristate "MAX3100 support" |
274 | depends on SPI | 287 | depends on SPI |
@@ -1447,4 +1460,30 @@ config SERIAL_ARC_NR_PORTS | |||
1447 | Set this to the number of serial ports you want the driver | 1460 | Set this to the number of serial ports you want the driver |
1448 | to support. | 1461 | to support. |
1449 | 1462 | ||
1463 | config SERIAL_RP2 | ||
1464 | tristate "Comtrol RocketPort EXPRESS/INFINITY support" | ||
1465 | depends on PCI | ||
1466 | select SERIAL_CORE | ||
1467 | help | ||
1468 | This driver supports the Comtrol RocketPort EXPRESS and | ||
1469 | RocketPort INFINITY families of PCI/PCIe multiport serial adapters. | ||
1470 | These adapters use a "RocketPort 2" ASIC that is not compatible | ||
1471 | with the original RocketPort driver (CONFIG_ROCKETPORT). | ||
1472 | |||
1473 | To compile this driver as a module, choose M here: the | ||
1474 | module will be called rp2. | ||
1475 | |||
1476 | If you want to compile this driver into the kernel, say Y here. If | ||
1477 | you don't have a suitable RocketPort card installed, say N. | ||
1478 | |||
1479 | config SERIAL_RP2_NR_UARTS | ||
1480 | int "Maximum number of RocketPort EXPRESS/INFINITY ports" | ||
1481 | depends on SERIAL_RP2 | ||
1482 | default "32" | ||
1483 | help | ||
1484 | If multiple cards are present, the default limit of 32 ports may | ||
1485 | need to be increased. | ||
1486 | |||
1450 | endmenu | 1487 | endmenu |
1488 | |||
1489 | endif # TTY | ||
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index df1b998c436b..eedfec40e3dd 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -80,6 +80,8 @@ obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o | |||
80 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | 80 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o |
81 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | 81 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o |
82 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o | 82 | obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o |
83 | obj-$(CONFIG_SERIAL_TEGRA) += serial-tegra.o | ||
83 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o | 84 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o |
84 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o | 85 | obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o |
85 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o | 86 | obj-$(CONFIG_SERIAL_ARC) += arc_uart.o |
87 | obj-$(CONFIG_SERIAL_RP2) += rp2.o | ||
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index 872f14ae43d2..c6bdb943726b 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c | |||
@@ -139,7 +139,7 @@ static void altera_jtaguart_rx_chars(struct altera_jtaguart *pp) | |||
139 | uart_insert_char(port, 0, 0, ch, flag); | 139 | uart_insert_char(port, 0, 0, ch, flag); |
140 | } | 140 | } |
141 | 141 | ||
142 | tty_flip_buffer_push(port->state->port.tty); | 142 | tty_flip_buffer_push(&port->state->port); |
143 | } | 143 | } |
144 | 144 | ||
145 | static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) | 145 | static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) |
@@ -493,11 +493,9 @@ static int __init altera_jtaguart_init(void) | |||
493 | if (rc) | 493 | if (rc) |
494 | return rc; | 494 | return rc; |
495 | rc = platform_driver_register(&altera_jtaguart_platform_driver); | 495 | rc = platform_driver_register(&altera_jtaguart_platform_driver); |
496 | if (rc) { | 496 | if (rc) |
497 | uart_unregister_driver(&altera_jtaguart_driver); | 497 | uart_unregister_driver(&altera_jtaguart_driver); |
498 | return rc; | 498 | return rc; |
499 | } | ||
500 | return 0; | ||
501 | } | 499 | } |
502 | 500 | ||
503 | static void __exit altera_jtaguart_exit(void) | 501 | static void __exit altera_jtaguart_exit(void) |
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 684a0808e1c7..13471dd95793 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -231,7 +231,7 @@ static void altera_uart_rx_chars(struct altera_uart *pp) | |||
231 | flag); | 231 | flag); |
232 | } | 232 | } |
233 | 233 | ||
234 | tty_flip_buffer_push(port->state->port.tty); | 234 | tty_flip_buffer_push(&port->state->port); |
235 | } | 235 | } |
236 | 236 | ||
237 | static void altera_uart_tx_chars(struct altera_uart *pp) | 237 | static void altera_uart_tx_chars(struct altera_uart *pp) |
@@ -637,11 +637,9 @@ static int __init altera_uart_init(void) | |||
637 | if (rc) | 637 | if (rc) |
638 | return rc; | 638 | return rc; |
639 | rc = platform_driver_register(&altera_uart_platform_driver); | 639 | rc = platform_driver_register(&altera_uart_platform_driver); |
640 | if (rc) { | 640 | if (rc) |
641 | uart_unregister_driver(&altera_uart_driver); | 641 | uart_unregister_driver(&altera_uart_driver); |
642 | return rc; | 642 | return rc; |
643 | } | ||
644 | return 0; | ||
645 | } | 643 | } |
646 | 644 | ||
647 | static void __exit altera_uart_exit(void) | 645 | static void __exit altera_uart_exit(void) |
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 22317dd16474..c36840519527 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c | |||
@@ -116,7 +116,6 @@ static void pl010_enable_ms(struct uart_port *port) | |||
116 | 116 | ||
117 | static void pl010_rx_chars(struct uart_amba_port *uap) | 117 | static void pl010_rx_chars(struct uart_amba_port *uap) |
118 | { | 118 | { |
119 | struct tty_struct *tty = uap->port.state->port.tty; | ||
120 | unsigned int status, ch, flag, rsr, max_count = 256; | 119 | unsigned int status, ch, flag, rsr, max_count = 256; |
121 | 120 | ||
122 | status = readb(uap->port.membase + UART01x_FR); | 121 | status = readb(uap->port.membase + UART01x_FR); |
@@ -165,7 +164,7 @@ static void pl010_rx_chars(struct uart_amba_port *uap) | |||
165 | status = readb(uap->port.membase + UART01x_FR); | 164 | status = readb(uap->port.membase + UART01x_FR); |
166 | } | 165 | } |
167 | spin_unlock(&uap->port.lock); | 166 | spin_unlock(&uap->port.lock); |
168 | tty_flip_buffer_push(tty); | 167 | tty_flip_buffer_push(&uap->port.state->port); |
169 | spin_lock(&uap->port.lock); | 168 | spin_lock(&uap->port.lock); |
170 | } | 169 | } |
171 | 170 | ||
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 7fca4022a8b2..3ea5408fcbeb 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -698,7 +698,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
698 | u32 pending, bool use_buf_b, | 698 | u32 pending, bool use_buf_b, |
699 | bool readfifo) | 699 | bool readfifo) |
700 | { | 700 | { |
701 | struct tty_struct *tty = uap->port.state->port.tty; | 701 | struct tty_port *port = &uap->port.state->port; |
702 | struct pl011_sgbuf *sgbuf = use_buf_b ? | 702 | struct pl011_sgbuf *sgbuf = use_buf_b ? |
703 | &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; | 703 | &uap->dmarx.sgbuf_b : &uap->dmarx.sgbuf_a; |
704 | struct device *dev = uap->dmarx.chan->device->dev; | 704 | struct device *dev = uap->dmarx.chan->device->dev; |
@@ -715,8 +715,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
715 | * Note that tty_insert_flip_buf() tries to take as many chars | 715 | * Note that tty_insert_flip_buf() tries to take as many chars |
716 | * as it can. | 716 | * as it can. |
717 | */ | 717 | */ |
718 | dma_count = tty_insert_flip_string(uap->port.state->port.tty, | 718 | dma_count = tty_insert_flip_string(port, sgbuf->buf, pending); |
719 | sgbuf->buf, pending); | ||
720 | 719 | ||
721 | /* Return buffer to device */ | 720 | /* Return buffer to device */ |
722 | dma_sync_sg_for_device(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE); | 721 | dma_sync_sg_for_device(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE); |
@@ -754,7 +753,7 @@ static void pl011_dma_rx_chars(struct uart_amba_port *uap, | |||
754 | dev_vdbg(uap->port.dev, | 753 | dev_vdbg(uap->port.dev, |
755 | "Took %d chars from DMA buffer and %d chars from the FIFO\n", | 754 | "Took %d chars from DMA buffer and %d chars from the FIFO\n", |
756 | dma_count, fifotaken); | 755 | dma_count, fifotaken); |
757 | tty_flip_buffer_push(tty); | 756 | tty_flip_buffer_push(port); |
758 | spin_lock(&uap->port.lock); | 757 | spin_lock(&uap->port.lock); |
759 | } | 758 | } |
760 | 759 | ||
@@ -1076,12 +1075,10 @@ static void pl011_enable_ms(struct uart_port *port) | |||
1076 | 1075 | ||
1077 | static void pl011_rx_chars(struct uart_amba_port *uap) | 1076 | static void pl011_rx_chars(struct uart_amba_port *uap) |
1078 | { | 1077 | { |
1079 | struct tty_struct *tty = uap->port.state->port.tty; | ||
1080 | |||
1081 | pl011_fifo_to_tty(uap); | 1078 | pl011_fifo_to_tty(uap); |
1082 | 1079 | ||
1083 | spin_unlock(&uap->port.lock); | 1080 | spin_unlock(&uap->port.lock); |
1084 | tty_flip_buffer_push(tty); | 1081 | tty_flip_buffer_push(&uap->port.state->port); |
1085 | /* | 1082 | /* |
1086 | * If we were temporarily out of DMA mode for a while, | 1083 | * If we were temporarily out of DMA mode for a while, |
1087 | * attempt to switch back to DMA mode again. | 1084 | * attempt to switch back to DMA mode again. |
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 59ae2b53e765..6331464d9101 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c | |||
@@ -78,7 +78,6 @@ static void apbuart_enable_ms(struct uart_port *port) | |||
78 | 78 | ||
79 | static void apbuart_rx_chars(struct uart_port *port) | 79 | static void apbuart_rx_chars(struct uart_port *port) |
80 | { | 80 | { |
81 | struct tty_struct *tty = port->state->port.tty; | ||
82 | unsigned int status, ch, rsr, flag; | 81 | unsigned int status, ch, rsr, flag; |
83 | unsigned int max_chars = port->fifosize; | 82 | unsigned int max_chars = port->fifosize; |
84 | 83 | ||
@@ -126,7 +125,7 @@ static void apbuart_rx_chars(struct uart_port *port) | |||
126 | status = UART_GET_STATUS(port); | 125 | status = UART_GET_STATUS(port); |
127 | } | 126 | } |
128 | 127 | ||
129 | tty_flip_buffer_push(tty); | 128 | tty_flip_buffer_push(&port->state->port); |
130 | } | 129 | } |
131 | 130 | ||
132 | static void apbuart_tx_chars(struct uart_port *port) | 131 | static void apbuart_tx_chars(struct uart_port *port) |
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index 505c490c0b44..27f20c57abed 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c | |||
@@ -297,10 +297,9 @@ static void ar933x_uart_set_termios(struct uart_port *port, | |||
297 | 297 | ||
298 | static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | 298 | static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) |
299 | { | 299 | { |
300 | struct tty_struct *tty; | 300 | struct tty_port *port = &up->port.state->port; |
301 | int max_count = 256; | 301 | int max_count = 256; |
302 | 302 | ||
303 | tty = tty_port_tty_get(&up->port.state->port); | ||
304 | do { | 303 | do { |
305 | unsigned int rdata; | 304 | unsigned int rdata; |
306 | unsigned char ch; | 305 | unsigned char ch; |
@@ -313,11 +312,6 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | |||
313 | ar933x_uart_write(up, AR933X_UART_DATA_REG, | 312 | ar933x_uart_write(up, AR933X_UART_DATA_REG, |
314 | AR933X_UART_DATA_RX_CSR); | 313 | AR933X_UART_DATA_RX_CSR); |
315 | 314 | ||
316 | if (!tty) { | ||
317 | /* discard the data if no tty available */ | ||
318 | continue; | ||
319 | } | ||
320 | |||
321 | up->port.icount.rx++; | 315 | up->port.icount.rx++; |
322 | ch = rdata & AR933X_UART_DATA_TX_RX_MASK; | 316 | ch = rdata & AR933X_UART_DATA_TX_RX_MASK; |
323 | 317 | ||
@@ -325,13 +319,10 @@ static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | |||
325 | continue; | 319 | continue; |
326 | 320 | ||
327 | if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) | 321 | if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) |
328 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 322 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
329 | } while (max_count-- > 0); | 323 | } while (max_count-- > 0); |
330 | 324 | ||
331 | if (tty) { | 325 | tty_flip_buffer_push(port); |
332 | tty_flip_buffer_push(tty); | ||
333 | tty_kref_put(tty); | ||
334 | } | ||
335 | } | 326 | } |
336 | 327 | ||
337 | static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) | 328 | static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) |
diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 3e0b3fac6a0e..d97e194b6bc5 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <linux/tty_flip.h> | 37 | #include <linux/tty_flip.h> |
38 | #include <linux/serial_core.h> | 38 | #include <linux/serial_core.h> |
39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
40 | #include <linux/of.h> | ||
41 | #include <linux/of_platform.h> | ||
40 | 42 | ||
41 | /************************************* | 43 | /************************************* |
42 | * ARC UART Hardware Specs | 44 | * ARC UART Hardware Specs |
@@ -209,12 +211,8 @@ static void arc_serial_start_tx(struct uart_port *port) | |||
209 | 211 | ||
210 | static void arc_serial_rx_chars(struct arc_uart_port *uart) | 212 | static void arc_serial_rx_chars(struct arc_uart_port *uart) |
211 | { | 213 | { |
212 | struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port); | ||
213 | unsigned int status, ch, flg = 0; | 214 | unsigned int status, ch, flg = 0; |
214 | 215 | ||
215 | if (!tty) | ||
216 | return; | ||
217 | |||
218 | /* | 216 | /* |
219 | * UART has 4 deep RX-FIFO. Driver's recongnition of this fact | 217 | * UART has 4 deep RX-FIFO. Driver's recongnition of this fact |
220 | * is very subtle. Here's how ... | 218 | * is very subtle. Here's how ... |
@@ -250,10 +248,8 @@ static void arc_serial_rx_chars(struct arc_uart_port *uart) | |||
250 | uart_insert_char(&uart->port, status, RXOERR, ch, flg); | 248 | uart_insert_char(&uart->port, status, RXOERR, ch, flg); |
251 | 249 | ||
252 | done: | 250 | done: |
253 | tty_flip_buffer_push(tty); | 251 | tty_flip_buffer_push(&uart->port.state->port); |
254 | } | 252 | } |
255 | |||
256 | tty_kref_put(tty); | ||
257 | } | 253 | } |
258 | 254 | ||
259 | /* | 255 | /* |
@@ -526,18 +522,37 @@ static struct uart_ops arc_serial_pops = { | |||
526 | }; | 522 | }; |
527 | 523 | ||
528 | static int | 524 | static int |
529 | arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | 525 | arc_uart_init_one(struct platform_device *pdev, int dev_id) |
530 | { | 526 | { |
531 | struct resource *res, *res2; | 527 | struct resource *res, *res2; |
532 | unsigned long *plat_data; | 528 | unsigned long *plat_data; |
533 | 529 | struct arc_uart_port *uart = &arc_uart_ports[dev_id]; | |
534 | if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) { | ||
535 | dev_err(&pdev->dev, "Wrong uart platform device id.\n"); | ||
536 | return -ENOENT; | ||
537 | } | ||
538 | 530 | ||
539 | plat_data = ((unsigned long *)(pdev->dev.platform_data)); | 531 | plat_data = ((unsigned long *)(pdev->dev.platform_data)); |
540 | uart->baud = plat_data[0]; | 532 | if (!plat_data) |
533 | return -ENODEV; | ||
534 | |||
535 | uart->is_emulated = !!plat_data[0]; /* workaround ISS bug */ | ||
536 | |||
537 | if (is_early_platform_device(pdev)) { | ||
538 | uart->port.uartclk = plat_data[1]; | ||
539 | uart->baud = plat_data[2]; | ||
540 | } else { | ||
541 | struct device_node *np = pdev->dev.of_node; | ||
542 | u32 val; | ||
543 | |||
544 | if (of_property_read_u32(np, "clock-frequency", &val)) { | ||
545 | dev_err(&pdev->dev, "clock-frequency property NOTset\n"); | ||
546 | return -EINVAL; | ||
547 | } | ||
548 | uart->port.uartclk = val; | ||
549 | |||
550 | if (of_property_read_u32(np, "current-speed", &val)) { | ||
551 | dev_err(&pdev->dev, "current-speed property NOT set\n"); | ||
552 | return -EINVAL; | ||
553 | } | ||
554 | uart->baud = val; | ||
555 | } | ||
541 | 556 | ||
542 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 557 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
543 | if (!res) | 558 | if (!res) |
@@ -557,10 +572,9 @@ arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | |||
557 | uart->port.dev = &pdev->dev; | 572 | uart->port.dev = &pdev->dev; |
558 | uart->port.iotype = UPIO_MEM; | 573 | uart->port.iotype = UPIO_MEM; |
559 | uart->port.flags = UPF_BOOT_AUTOCONF; | 574 | uart->port.flags = UPF_BOOT_AUTOCONF; |
560 | uart->port.line = pdev->id; | 575 | uart->port.line = dev_id; |
561 | uart->port.ops = &arc_serial_pops; | 576 | uart->port.ops = &arc_serial_pops; |
562 | 577 | ||
563 | uart->port.uartclk = plat_data[1]; | ||
564 | uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; | 578 | uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; |
565 | 579 | ||
566 | /* | 580 | /* |
@@ -569,9 +583,6 @@ arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) | |||
569 | */ | 583 | */ |
570 | uart->port.ignore_status_mask = 0; | 584 | uart->port.ignore_status_mask = 0; |
571 | 585 | ||
572 | /* Real Hardware vs. emulated to work around a bug */ | ||
573 | uart->is_emulated = !!plat_data[2]; | ||
574 | |||
575 | return 0; | 586 | return 0; |
576 | } | 587 | } |
577 | 588 | ||
@@ -648,45 +659,50 @@ static __init void early_serial_write(struct console *con, const char *s, | |||
648 | } | 659 | } |
649 | } | 660 | } |
650 | 661 | ||
651 | static struct __initdata console arc_early_serial_console = { | 662 | static struct console arc_early_serial_console __initdata = { |
652 | .name = "early_ARCuart", | 663 | .name = "early_ARCuart", |
653 | .write = early_serial_write, | 664 | .write = early_serial_write, |
654 | .flags = CON_PRINTBUFFER | CON_BOOT, | 665 | .flags = CON_PRINTBUFFER | CON_BOOT, |
655 | .index = -1 | 666 | .index = -1 |
656 | }; | 667 | }; |
657 | 668 | ||
658 | static int arc_serial_probe_earlyprintk(struct platform_device *pdev) | 669 | static int __init arc_serial_probe_earlyprintk(struct platform_device *pdev) |
659 | { | 670 | { |
660 | arc_early_serial_console.index = pdev->id; | 671 | int dev_id = pdev->id < 0 ? 0 : pdev->id; |
672 | int rc; | ||
673 | |||
674 | arc_early_serial_console.index = dev_id; | ||
661 | 675 | ||
662 | arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]); | 676 | rc = arc_uart_init_one(pdev, dev_id); |
677 | if (rc) | ||
678 | panic("early console init failed\n"); | ||
663 | 679 | ||
664 | arc_serial_console_setup(&arc_early_serial_console, NULL); | 680 | arc_serial_console_setup(&arc_early_serial_console, NULL); |
665 | 681 | ||
666 | register_console(&arc_early_serial_console); | 682 | register_console(&arc_early_serial_console); |
667 | return 0; | 683 | return 0; |
668 | } | 684 | } |
669 | #else | ||
670 | static int arc_serial_probe_earlyprintk(struct platform_device *pdev) | ||
671 | { | ||
672 | return -ENODEV; | ||
673 | } | ||
674 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | 685 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ |
675 | 686 | ||
676 | static int arc_serial_probe(struct platform_device *pdev) | 687 | static int arc_serial_probe(struct platform_device *pdev) |
677 | { | 688 | { |
678 | struct arc_uart_port *uart; | 689 | int rc, dev_id; |
679 | int rc; | 690 | struct device_node *np = pdev->dev.of_node; |
691 | |||
692 | /* no device tree device */ | ||
693 | if (!np) | ||
694 | return -ENODEV; | ||
680 | 695 | ||
681 | if (is_early_platform_device(pdev)) | 696 | dev_id = of_alias_get_id(np, "serial"); |
682 | return arc_serial_probe_earlyprintk(pdev); | 697 | if (dev_id < 0) |
698 | dev_id = 0; | ||
683 | 699 | ||
684 | uart = &arc_uart_ports[pdev->id]; | 700 | rc = arc_uart_init_one(pdev, dev_id); |
685 | rc = arc_uart_init_one(pdev, uart); | ||
686 | if (rc) | 701 | if (rc) |
687 | return rc; | 702 | return rc; |
688 | 703 | ||
689 | return uart_add_one_port(&arc_uart_driver, &uart->port); | 704 | rc = uart_add_one_port(&arc_uart_driver, &arc_uart_ports[dev_id].port); |
705 | return rc; | ||
690 | } | 706 | } |
691 | 707 | ||
692 | static int arc_serial_remove(struct platform_device *pdev) | 708 | static int arc_serial_remove(struct platform_device *pdev) |
@@ -695,16 +711,32 @@ static int arc_serial_remove(struct platform_device *pdev) | |||
695 | return 0; | 711 | return 0; |
696 | } | 712 | } |
697 | 713 | ||
714 | static const struct of_device_id arc_uart_dt_ids[] = { | ||
715 | { .compatible = "snps,arc-uart" }, | ||
716 | { /* Sentinel */ } | ||
717 | }; | ||
718 | MODULE_DEVICE_TABLE(of, arc_uart_dt_ids); | ||
719 | |||
698 | static struct platform_driver arc_platform_driver = { | 720 | static struct platform_driver arc_platform_driver = { |
699 | .probe = arc_serial_probe, | 721 | .probe = arc_serial_probe, |
700 | .remove = arc_serial_remove, | 722 | .remove = arc_serial_remove, |
701 | .driver = { | 723 | .driver = { |
702 | .name = DRIVER_NAME, | 724 | .name = DRIVER_NAME, |
703 | .owner = THIS_MODULE, | 725 | .owner = THIS_MODULE, |
726 | .of_match_table = arc_uart_dt_ids, | ||
704 | }, | 727 | }, |
705 | }; | 728 | }; |
706 | 729 | ||
707 | #ifdef CONFIG_SERIAL_ARC_CONSOLE | 730 | #ifdef CONFIG_SERIAL_ARC_CONSOLE |
731 | |||
732 | static struct platform_driver early_arc_platform_driver __initdata = { | ||
733 | .probe = arc_serial_probe_earlyprintk, | ||
734 | .remove = arc_serial_remove, | ||
735 | .driver = { | ||
736 | .name = DRIVER_NAME, | ||
737 | .owner = THIS_MODULE, | ||
738 | }, | ||
739 | }; | ||
708 | /* | 740 | /* |
709 | * Register an early platform driver of "earlyprintk" class. | 741 | * Register an early platform driver of "earlyprintk" class. |
710 | * ARCH platform code installs the driver and probes the early devices | 742 | * ARCH platform code installs the driver and probes the early devices |
@@ -712,7 +744,7 @@ static struct platform_driver arc_platform_driver = { | |||
712 | * or it could be done independently, for all "earlyprintk" class drivers. | 744 | * or it could be done independently, for all "earlyprintk" class drivers. |
713 | * [see arch/arc/plat-arcfpga/platform.c] | 745 | * [see arch/arc/plat-arcfpga/platform.c] |
714 | */ | 746 | */ |
715 | early_platform_init("earlyprintk", &arc_platform_driver); | 747 | early_platform_init("earlyprintk", &early_arc_platform_driver); |
716 | 748 | ||
717 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ | 749 | #endif /* CONFIG_SERIAL_ARC_CONSOLE */ |
718 | 750 | ||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 922e85aeb63a..d4a7c241b751 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -774,14 +774,14 @@ static void atmel_rx_from_ring(struct uart_port *port) | |||
774 | * uart_start(), which takes the lock. | 774 | * uart_start(), which takes the lock. |
775 | */ | 775 | */ |
776 | spin_unlock(&port->lock); | 776 | spin_unlock(&port->lock); |
777 | tty_flip_buffer_push(port->state->port.tty); | 777 | tty_flip_buffer_push(&port->state->port); |
778 | spin_lock(&port->lock); | 778 | spin_lock(&port->lock); |
779 | } | 779 | } |
780 | 780 | ||
781 | static void atmel_rx_from_dma(struct uart_port *port) | 781 | static void atmel_rx_from_dma(struct uart_port *port) |
782 | { | 782 | { |
783 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 783 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
784 | struct tty_struct *tty = port->state->port.tty; | 784 | struct tty_port *tport = &port->state->port; |
785 | struct atmel_dma_buffer *pdc; | 785 | struct atmel_dma_buffer *pdc; |
786 | int rx_idx = atmel_port->pdc_rx_idx; | 786 | int rx_idx = atmel_port->pdc_rx_idx; |
787 | unsigned int head; | 787 | unsigned int head; |
@@ -820,7 +820,8 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
820 | */ | 820 | */ |
821 | count = head - tail; | 821 | count = head - tail; |
822 | 822 | ||
823 | tty_insert_flip_string(tty, pdc->buf + pdc->ofs, count); | 823 | tty_insert_flip_string(tport, pdc->buf + pdc->ofs, |
824 | count); | ||
824 | 825 | ||
825 | dma_sync_single_for_device(port->dev, pdc->dma_addr, | 826 | dma_sync_single_for_device(port->dev, pdc->dma_addr, |
826 | pdc->dma_size, DMA_FROM_DEVICE); | 827 | pdc->dma_size, DMA_FROM_DEVICE); |
@@ -848,7 +849,7 @@ static void atmel_rx_from_dma(struct uart_port *port) | |||
848 | * uart_start(), which takes the lock. | 849 | * uart_start(), which takes the lock. |
849 | */ | 850 | */ |
850 | spin_unlock(&port->lock); | 851 | spin_unlock(&port->lock); |
851 | tty_flip_buffer_push(tty); | 852 | tty_flip_buffer_push(tport); |
852 | spin_lock(&port->lock); | 853 | spin_lock(&port->lock); |
853 | 854 | ||
854 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); | 855 | UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT); |
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index c76a226080f2..719594e5fc21 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c | |||
@@ -235,14 +235,13 @@ static const char *bcm_uart_type(struct uart_port *port) | |||
235 | */ | 235 | */ |
236 | static void bcm_uart_do_rx(struct uart_port *port) | 236 | static void bcm_uart_do_rx(struct uart_port *port) |
237 | { | 237 | { |
238 | struct tty_struct *tty; | 238 | struct tty_port *port = &port->state->port; |
239 | unsigned int max_count; | 239 | unsigned int max_count; |
240 | 240 | ||
241 | /* limit number of char read in interrupt, should not be | 241 | /* limit number of char read in interrupt, should not be |
242 | * higher than fifo size anyway since we're much faster than | 242 | * higher than fifo size anyway since we're much faster than |
243 | * serial port */ | 243 | * serial port */ |
244 | max_count = 32; | 244 | max_count = 32; |
245 | tty = port->state->port.tty; | ||
246 | do { | 245 | do { |
247 | unsigned int iestat, c, cstat; | 246 | unsigned int iestat, c, cstat; |
248 | char flag; | 247 | char flag; |
@@ -261,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port) | |||
261 | bcm_uart_writel(port, val, UART_CTL_REG); | 260 | bcm_uart_writel(port, val, UART_CTL_REG); |
262 | 261 | ||
263 | port->icount.overrun++; | 262 | port->icount.overrun++; |
264 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 263 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
265 | } | 264 | } |
266 | 265 | ||
267 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) | 266 | if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) |
@@ -300,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port) | |||
300 | 299 | ||
301 | 300 | ||
302 | if ((cstat & port->ignore_status_mask) == 0) | 301 | if ((cstat & port->ignore_status_mask) == 0) |
303 | tty_insert_flip_char(tty, c, flag); | 302 | tty_insert_flip_char(port, c, flag); |
304 | 303 | ||
305 | } while (--max_count); | 304 | } while (--max_count); |
306 | 305 | ||
307 | tty_flip_buffer_push(tty); | 306 | tty_flip_buffer_push(port); |
308 | } | 307 | } |
309 | 308 | ||
310 | /* | 309 | /* |
diff --git a/drivers/tty/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index f5d117379b60..487c173b0f72 100644 --- a/drivers/tty/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c | |||
@@ -149,7 +149,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate) | |||
149 | static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | 149 | static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) |
150 | { | 150 | { |
151 | struct sport_uart_port *up = dev_id; | 151 | struct sport_uart_port *up = dev_id; |
152 | struct tty_struct *tty = up->port.state->port.tty; | 152 | struct tty_port *port = &up->port.state->port; |
153 | unsigned int ch; | 153 | unsigned int ch; |
154 | 154 | ||
155 | spin_lock(&up->port.lock); | 155 | spin_lock(&up->port.lock); |
@@ -159,9 +159,10 @@ static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id) | |||
159 | up->port.icount.rx++; | 159 | up->port.icount.rx++; |
160 | 160 | ||
161 | if (!uart_handle_sysrq_char(&up->port, ch)) | 161 | if (!uart_handle_sysrq_char(&up->port, ch)) |
162 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 162 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
163 | } | 163 | } |
164 | tty_flip_buffer_push(tty); | 164 | /* XXX this won't deadlock with lowlat? */ |
165 | tty_flip_buffer_push(port); | ||
165 | 166 | ||
166 | spin_unlock(&up->port.lock); | 167 | spin_unlock(&up->port.lock); |
167 | 168 | ||
@@ -182,7 +183,6 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id) | |||
182 | static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | 183 | static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) |
183 | { | 184 | { |
184 | struct sport_uart_port *up = dev_id; | 185 | struct sport_uart_port *up = dev_id; |
185 | struct tty_struct *tty = up->port.state->port.tty; | ||
186 | unsigned int stat = SPORT_GET_STAT(up); | 186 | unsigned int stat = SPORT_GET_STAT(up); |
187 | 187 | ||
188 | spin_lock(&up->port.lock); | 188 | spin_lock(&up->port.lock); |
@@ -190,7 +190,7 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
190 | /* Overflow in RX FIFO */ | 190 | /* Overflow in RX FIFO */ |
191 | if (stat & ROVF) { | 191 | if (stat & ROVF) { |
192 | up->port.icount.overrun++; | 192 | up->port.icount.overrun++; |
193 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 193 | tty_insert_flip_char(&up->port.state->port, 0, TTY_OVERRUN); |
194 | SPORT_PUT_STAT(up, ROVF); /* Clear ROVF bit */ | 194 | SPORT_PUT_STAT(up, ROVF); /* Clear ROVF bit */ |
195 | } | 195 | } |
196 | /* These should not happen */ | 196 | /* These should not happen */ |
@@ -205,6 +205,8 @@ static irqreturn_t sport_uart_err_irq(int irq, void *dev_id) | |||
205 | SSYNC(); | 205 | SSYNC(); |
206 | 206 | ||
207 | spin_unlock(&up->port.lock); | 207 | spin_unlock(&up->port.lock); |
208 | /* XXX we don't push the overrun bit to TTY? */ | ||
209 | |||
208 | return IRQ_HANDLED; | 210 | return IRQ_HANDLED; |
209 | } | 211 | } |
210 | 212 | ||
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 2e2b2c1cb722..12dceda9db33 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -223,7 +223,6 @@ static void bfin_serial_enable_ms(struct uart_port *port) | |||
223 | #ifdef CONFIG_SERIAL_BFIN_PIO | 223 | #ifdef CONFIG_SERIAL_BFIN_PIO |
224 | static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | 224 | static void bfin_serial_rx_chars(struct bfin_serial_port *uart) |
225 | { | 225 | { |
226 | struct tty_struct *tty = NULL; | ||
227 | unsigned int status, ch, flg; | 226 | unsigned int status, ch, flg; |
228 | static struct timeval anomaly_start = { .tv_sec = 0 }; | 227 | static struct timeval anomaly_start = { .tv_sec = 0 }; |
229 | 228 | ||
@@ -242,11 +241,9 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
242 | return; | 241 | return; |
243 | } | 242 | } |
244 | 243 | ||
245 | if (!uart->port.state || !uart->port.state->port.tty) | 244 | if (!uart->port.state) |
246 | return; | 245 | return; |
247 | #endif | 246 | #endif |
248 | tty = uart->port.state->port.tty; | ||
249 | |||
250 | if (ANOMALY_05000363) { | 247 | if (ANOMALY_05000363) { |
251 | /* The BF533 (and BF561) family of processors have a nice anomaly | 248 | /* The BF533 (and BF561) family of processors have a nice anomaly |
252 | * where they continuously generate characters for a "single" break. | 249 | * where they continuously generate characters for a "single" break. |
@@ -325,7 +322,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) | |||
325 | uart_insert_char(&uart->port, status, OE, ch, flg); | 322 | uart_insert_char(&uart->port, status, OE, ch, flg); |
326 | 323 | ||
327 | ignore_char: | 324 | ignore_char: |
328 | tty_flip_buffer_push(tty); | 325 | tty_flip_buffer_push(&uart->port.state->port); |
329 | } | 326 | } |
330 | 327 | ||
331 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) | 328 | static void bfin_serial_tx_chars(struct bfin_serial_port *uart) |
@@ -426,7 +423,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) | |||
426 | 423 | ||
427 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | 424 | static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) |
428 | { | 425 | { |
429 | struct tty_struct *tty = uart->port.state->port.tty; | ||
430 | int i, flg, status; | 426 | int i, flg, status; |
431 | 427 | ||
432 | status = UART_GET_LSR(uart); | 428 | status = UART_GET_LSR(uart); |
@@ -471,7 +467,7 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) | |||
471 | } | 467 | } |
472 | 468 | ||
473 | dma_ignore_char: | 469 | dma_ignore_char: |
474 | tty_flip_buffer_push(tty); | 470 | tty_flip_buffer_push(&uart->port.state->port); |
475 | } | 471 | } |
476 | 472 | ||
477 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) | 473 | void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) |
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 3fd2526d121e..bfb17968c8db 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -85,12 +85,8 @@ static void uart_clps711x_enable_ms(struct uart_port *port) | |||
85 | static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) | 85 | static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) |
86 | { | 86 | { |
87 | struct uart_port *port = dev_id; | 87 | struct uart_port *port = dev_id; |
88 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
89 | unsigned int status, ch, flg; | 88 | unsigned int status, ch, flg; |
90 | 89 | ||
91 | if (!tty) | ||
92 | return IRQ_HANDLED; | ||
93 | |||
94 | for (;;) { | 90 | for (;;) { |
95 | status = clps_readl(SYSFLG(port)); | 91 | status = clps_readl(SYSFLG(port)); |
96 | if (status & SYSFLG_URXFE) | 92 | if (status & SYSFLG_URXFE) |
@@ -130,9 +126,7 @@ static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) | |||
130 | uart_insert_char(port, status, UARTDR_OVERR, ch, flg); | 126 | uart_insert_char(port, status, UARTDR_OVERR, ch, flg); |
131 | } | 127 | } |
132 | 128 | ||
133 | tty_flip_buffer_push(tty); | 129 | tty_flip_buffer_push(&port->state->port); |
134 | |||
135 | tty_kref_put(tty); | ||
136 | 130 | ||
137 | return IRQ_HANDLED; | 131 | return IRQ_HANDLED; |
138 | } | 132 | } |
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index ad0caf176808..97f4e1858649 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c | |||
@@ -245,7 +245,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
245 | int i; | 245 | int i; |
246 | unsigned char ch; | 246 | unsigned char ch; |
247 | u8 *cp; | 247 | u8 *cp; |
248 | struct tty_struct *tty = port->state->port.tty; | 248 | struct tty_port *tport = &port->state->port; |
249 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 249 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
250 | cbd_t __iomem *bdp; | 250 | cbd_t __iomem *bdp; |
251 | u16 status; | 251 | u16 status; |
@@ -276,7 +276,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
276 | /* If we have not enough room in tty flip buffer, then we try | 276 | /* If we have not enough room in tty flip buffer, then we try |
277 | * later, which will be the next rx-interrupt or a timeout | 277 | * later, which will be the next rx-interrupt or a timeout |
278 | */ | 278 | */ |
279 | if(tty_buffer_request_room(tty, i) < i) { | 279 | if (tty_buffer_request_room(tport, i) < i) { |
280 | printk(KERN_WARNING "No room in flip buffer\n"); | 280 | printk(KERN_WARNING "No room in flip buffer\n"); |
281 | return; | 281 | return; |
282 | } | 282 | } |
@@ -302,7 +302,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
302 | } | 302 | } |
303 | #endif | 303 | #endif |
304 | error_return: | 304 | error_return: |
305 | tty_insert_flip_char(tty, ch, flg); | 305 | tty_insert_flip_char(tport, ch, flg); |
306 | 306 | ||
307 | } /* End while (i--) */ | 307 | } /* End while (i--) */ |
308 | 308 | ||
@@ -322,7 +322,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
322 | pinfo->rx_cur = bdp; | 322 | pinfo->rx_cur = bdp; |
323 | 323 | ||
324 | /* activate BH processing */ | 324 | /* activate BH processing */ |
325 | tty_flip_buffer_push(tty); | 325 | tty_flip_buffer_push(tport); |
326 | 326 | ||
327 | return; | 327 | return; |
328 | 328 | ||
@@ -507,7 +507,7 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
507 | 507 | ||
508 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); | 508 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); |
509 | if (baud < HW_BUF_SPD_THRESHOLD || | 509 | if (baud < HW_BUF_SPD_THRESHOLD || |
510 | (pinfo->port.state && pinfo->port.state->port.tty->low_latency)) | 510 | (pinfo->port.state && pinfo->port.state->port.low_latency)) |
511 | pinfo->rx_fifosize = 1; | 511 | pinfo->rx_fifosize = 1; |
512 | else | 512 | else |
513 | pinfo->rx_fifosize = RX_BUF_SIZE; | 513 | pinfo->rx_fifosize = RX_BUF_SIZE; |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 35ee6a2c6877..5f37c31e32bc 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -1760,8 +1760,7 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl | |||
1760 | 1760 | ||
1761 | info->icount.rx++; | 1761 | info->icount.rx++; |
1762 | } else { | 1762 | } else { |
1763 | struct tty_struct *tty = info->port.tty; | 1763 | tty_insert_flip_char(&info->port, data, flag); |
1764 | tty_insert_flip_char(tty, data, flag); | ||
1765 | info->icount.rx++; | 1764 | info->icount.rx++; |
1766 | } | 1765 | } |
1767 | 1766 | ||
@@ -2105,22 +2104,15 @@ static int force_eop_if_needed(struct e100_serial *info) | |||
2105 | 2104 | ||
2106 | static void flush_to_flip_buffer(struct e100_serial *info) | 2105 | static void flush_to_flip_buffer(struct e100_serial *info) |
2107 | { | 2106 | { |
2108 | struct tty_struct *tty; | ||
2109 | struct etrax_recv_buffer *buffer; | 2107 | struct etrax_recv_buffer *buffer; |
2110 | unsigned long flags; | 2108 | unsigned long flags; |
2111 | 2109 | ||
2112 | local_irq_save(flags); | 2110 | local_irq_save(flags); |
2113 | tty = info->port.tty; | ||
2114 | |||
2115 | if (!tty) { | ||
2116 | local_irq_restore(flags); | ||
2117 | return; | ||
2118 | } | ||
2119 | 2111 | ||
2120 | while ((buffer = info->first_recv_buffer) != NULL) { | 2112 | while ((buffer = info->first_recv_buffer) != NULL) { |
2121 | unsigned int count = buffer->length; | 2113 | unsigned int count = buffer->length; |
2122 | 2114 | ||
2123 | tty_insert_flip_string(tty, buffer->buffer, count); | 2115 | tty_insert_flip_string(&info->port, buffer->buffer, count); |
2124 | info->recv_cnt -= count; | 2116 | info->recv_cnt -= count; |
2125 | 2117 | ||
2126 | if (count == buffer->length) { | 2118 | if (count == buffer->length) { |
@@ -2139,7 +2131,7 @@ static void flush_to_flip_buffer(struct e100_serial *info) | |||
2139 | local_irq_restore(flags); | 2131 | local_irq_restore(flags); |
2140 | 2132 | ||
2141 | /* This includes a check for low-latency */ | 2133 | /* This includes a check for low-latency */ |
2142 | tty_flip_buffer_push(tty); | 2134 | tty_flip_buffer_push(&info->port); |
2143 | } | 2135 | } |
2144 | 2136 | ||
2145 | static void check_flush_timeout(struct e100_serial *info) | 2137 | static void check_flush_timeout(struct e100_serial *info) |
@@ -2275,12 +2267,6 @@ static | |||
2275 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) | 2267 | struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) |
2276 | { | 2268 | { |
2277 | unsigned long data_read; | 2269 | unsigned long data_read; |
2278 | struct tty_struct *tty = info->port.tty; | ||
2279 | |||
2280 | if (!tty) { | ||
2281 | printk("!NO TTY!\n"); | ||
2282 | return info; | ||
2283 | } | ||
2284 | 2270 | ||
2285 | /* Read data and status at the same time */ | 2271 | /* Read data and status at the same time */ |
2286 | data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); | 2272 | data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); |
@@ -2338,8 +2324,7 @@ more_data: | |||
2338 | data_in, data_read); | 2324 | data_in, data_read); |
2339 | char flag = TTY_NORMAL; | 2325 | char flag = TTY_NORMAL; |
2340 | if (info->errorcode == ERRCODE_INSERT_BREAK) { | 2326 | if (info->errorcode == ERRCODE_INSERT_BREAK) { |
2341 | struct tty_struct *tty = info->port.tty; | 2327 | tty_insert_flip_char(&info->port, 0, flag); |
2342 | tty_insert_flip_char(tty, 0, flag); | ||
2343 | info->icount.rx++; | 2328 | info->icount.rx++; |
2344 | } | 2329 | } |
2345 | 2330 | ||
@@ -2353,7 +2338,7 @@ more_data: | |||
2353 | info->icount.frame++; | 2338 | info->icount.frame++; |
2354 | flag = TTY_FRAME; | 2339 | flag = TTY_FRAME; |
2355 | } | 2340 | } |
2356 | tty_insert_flip_char(tty, data, flag); | 2341 | tty_insert_flip_char(&info->port, data, flag); |
2357 | info->errorcode = 0; | 2342 | info->errorcode = 0; |
2358 | } | 2343 | } |
2359 | info->break_detected_cnt = 0; | 2344 | info->break_detected_cnt = 0; |
@@ -2369,7 +2354,7 @@ more_data: | |||
2369 | log_int(rdpc(), 0, 0); | 2354 | log_int(rdpc(), 0, 0); |
2370 | } | 2355 | } |
2371 | ); | 2356 | ); |
2372 | tty_insert_flip_char(tty, | 2357 | tty_insert_flip_char(&info->port, |
2373 | IO_EXTRACT(R_SERIAL0_READ, data_in, data_read), | 2358 | IO_EXTRACT(R_SERIAL0_READ, data_in, data_read), |
2374 | TTY_NORMAL); | 2359 | TTY_NORMAL); |
2375 | } else { | 2360 | } else { |
@@ -2384,7 +2369,7 @@ more_data: | |||
2384 | goto more_data; | 2369 | goto more_data; |
2385 | } | 2370 | } |
2386 | 2371 | ||
2387 | tty_flip_buffer_push(info->port.tty); | 2372 | tty_flip_buffer_push(&info->port); |
2388 | return info; | 2373 | return info; |
2389 | } | 2374 | } |
2390 | 2375 | ||
@@ -3137,7 +3122,7 @@ static int rs_raw_write(struct tty_struct *tty, | |||
3137 | 3122 | ||
3138 | /* first some sanity checks */ | 3123 | /* first some sanity checks */ |
3139 | 3124 | ||
3140 | if (!tty || !info->xmit.buf) | 3125 | if (!info->xmit.buf) |
3141 | return 0; | 3126 | return 0; |
3142 | 3127 | ||
3143 | #ifdef SERIAL_DEBUG_DATA | 3128 | #ifdef SERIAL_DEBUG_DATA |
@@ -3464,7 +3449,7 @@ set_serial_info(struct e100_serial *info, | |||
3464 | info->type = new_serial.type; | 3449 | info->type = new_serial.type; |
3465 | info->close_delay = new_serial.close_delay; | 3450 | info->close_delay = new_serial.close_delay; |
3466 | info->closing_wait = new_serial.closing_wait; | 3451 | info->closing_wait = new_serial.closing_wait; |
3467 | info->port.tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 3452 | info->port.low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
3468 | 3453 | ||
3469 | check_and_exit: | 3454 | check_and_exit: |
3470 | if (info->flags & ASYNC_INITIALIZED) { | 3455 | if (info->flags & ASYNC_INITIALIZED) { |
@@ -4108,7 +4093,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4108 | tty->driver_data = info; | 4093 | tty->driver_data = info; |
4109 | info->port.tty = tty; | 4094 | info->port.tty = tty; |
4110 | 4095 | ||
4111 | tty->low_latency = !!(info->flags & ASYNC_LOW_LATENCY); | 4096 | info->port.low_latency = !!(info->flags & ASYNC_LOW_LATENCY); |
4112 | 4097 | ||
4113 | /* | 4098 | /* |
4114 | * If the port is in the middle of closing, bail out now | 4099 | * If the port is in the middle of closing, bail out now |
diff --git a/drivers/tty/serial/dz.c b/drivers/tty/serial/dz.c index 6491b8644a7f..2f2b2e538a54 100644 --- a/drivers/tty/serial/dz.c +++ b/drivers/tty/serial/dz.c | |||
@@ -187,7 +187,6 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
187 | { | 187 | { |
188 | struct uart_port *uport; | 188 | struct uart_port *uport; |
189 | struct dz_port *dport = &mux->dport[0]; | 189 | struct dz_port *dport = &mux->dport[0]; |
190 | struct tty_struct *tty = NULL; | ||
191 | struct uart_icount *icount; | 190 | struct uart_icount *icount; |
192 | int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; | 191 | int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 }; |
193 | unsigned char ch, flag; | 192 | unsigned char ch, flag; |
@@ -197,7 +196,6 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
197 | while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { | 196 | while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) { |
198 | dport = &mux->dport[LINE(status)]; | 197 | dport = &mux->dport[LINE(status)]; |
199 | uport = &dport->port; | 198 | uport = &dport->port; |
200 | tty = uport->state->port.tty; /* point to the proper dev */ | ||
201 | 199 | ||
202 | ch = UCHAR(status); /* grab the char */ | 200 | ch = UCHAR(status); /* grab the char */ |
203 | flag = TTY_NORMAL; | 201 | flag = TTY_NORMAL; |
@@ -249,7 +247,7 @@ static inline void dz_receive_chars(struct dz_mux *mux) | |||
249 | } | 247 | } |
250 | for (i = 0; i < DZ_NB_PORT; i++) | 248 | for (i = 0; i < DZ_NB_PORT; i++) |
251 | if (lines_rx[i]) | 249 | if (lines_rx[i]) |
252 | tty_flip_buffer_push(mux->dport[i].port.state->port.tty); | 250 | tty_flip_buffer_push(&mux->dport[i].port.state->port); |
253 | } | 251 | } |
254 | 252 | ||
255 | /* | 253 | /* |
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index a8cbb2670521..7d199c8e1a75 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c | |||
@@ -81,6 +81,7 @@ struct efm32_uart_port { | |||
81 | struct uart_port port; | 81 | struct uart_port port; |
82 | unsigned int txirq; | 82 | unsigned int txirq; |
83 | struct clk *clk; | 83 | struct clk *clk; |
84 | struct efm32_uart_pdata pdata; | ||
84 | }; | 85 | }; |
85 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) | 86 | #define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) |
86 | #define efm_debug(efm_port, format, arg...) \ | 87 | #define efm_debug(efm_port, format, arg...) \ |
@@ -194,8 +195,7 @@ static void efm32_uart_break_ctl(struct uart_port *port, int ctl) | |||
194 | /* not possible without fiddling with gpios */ | 195 | /* not possible without fiddling with gpios */ |
195 | } | 196 | } |
196 | 197 | ||
197 | static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, | 198 | static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port) |
198 | struct tty_struct *tty) | ||
199 | { | 199 | { |
200 | struct uart_port *port = &efm_port->port; | 200 | struct uart_port *port = &efm_port->port; |
201 | 201 | ||
@@ -237,8 +237,8 @@ static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, | |||
237 | rxdata & UARTn_RXDATAX_RXDATA__MASK)) | 237 | rxdata & UARTn_RXDATAX_RXDATA__MASK)) |
238 | continue; | 238 | continue; |
239 | 239 | ||
240 | if (tty && (rxdata & port->ignore_status_mask) == 0) | 240 | if ((rxdata & port->ignore_status_mask) == 0) |
241 | tty_insert_flip_char(tty, | 241 | tty_insert_flip_char(&port->state->port, |
242 | rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); | 242 | rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); |
243 | } | 243 | } |
244 | } | 244 | } |
@@ -249,15 +249,13 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) | |||
249 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); | 249 | u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); |
250 | int handled = IRQ_NONE; | 250 | int handled = IRQ_NONE; |
251 | struct uart_port *port = &efm_port->port; | 251 | struct uart_port *port = &efm_port->port; |
252 | struct tty_struct *tty; | 252 | struct tty_port *tport = &port->state->port; |
253 | 253 | ||
254 | spin_lock(&port->lock); | 254 | spin_lock(&port->lock); |
255 | 255 | ||
256 | tty = tty_kref_get(port->state->port.tty); | ||
257 | |||
258 | if (irqflag & UARTn_IF_RXDATAV) { | 256 | if (irqflag & UARTn_IF_RXDATAV) { |
259 | efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); | 257 | efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); |
260 | efm32_uart_rx_chars(efm_port, tty); | 258 | efm32_uart_rx_chars(efm_port); |
261 | 259 | ||
262 | handled = IRQ_HANDLED; | 260 | handled = IRQ_HANDLED; |
263 | } | 261 | } |
@@ -265,16 +263,12 @@ static irqreturn_t efm32_uart_rxirq(int irq, void *data) | |||
265 | if (irqflag & UARTn_IF_RXOF) { | 263 | if (irqflag & UARTn_IF_RXOF) { |
266 | efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); | 264 | efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); |
267 | port->icount.overrun++; | 265 | port->icount.overrun++; |
268 | if (tty) | 266 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
269 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
270 | 267 | ||
271 | handled = IRQ_HANDLED; | 268 | handled = IRQ_HANDLED; |
272 | } | 269 | } |
273 | 270 | ||
274 | if (tty) { | 271 | tty_flip_buffer_push(tport); |
275 | tty_flip_buffer_push(tty); | ||
276 | tty_kref_put(tty); | ||
277 | } | ||
278 | 272 | ||
279 | spin_unlock(&port->lock); | 273 | spin_unlock(&port->lock); |
280 | 274 | ||
@@ -300,13 +294,8 @@ static irqreturn_t efm32_uart_txirq(int irq, void *data) | |||
300 | static int efm32_uart_startup(struct uart_port *port) | 294 | static int efm32_uart_startup(struct uart_port *port) |
301 | { | 295 | { |
302 | struct efm32_uart_port *efm_port = to_efm_port(port); | 296 | struct efm32_uart_port *efm_port = to_efm_port(port); |
303 | u32 location = 0; | ||
304 | struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); | ||
305 | int ret; | 297 | int ret; |
306 | 298 | ||
307 | if (pdata) | ||
308 | location = UARTn_ROUTE_LOCATION(pdata->location); | ||
309 | |||
310 | ret = clk_enable(efm_port->clk); | 299 | ret = clk_enable(efm_port->clk); |
311 | if (ret) { | 300 | if (ret) { |
312 | efm_debug(efm_port, "failed to enable clk\n"); | 301 | efm_debug(efm_port, "failed to enable clk\n"); |
@@ -315,7 +304,9 @@ static int efm32_uart_startup(struct uart_port *port) | |||
315 | port->uartclk = clk_get_rate(efm_port->clk); | 304 | port->uartclk = clk_get_rate(efm_port->clk); |
316 | 305 | ||
317 | /* Enable pins at configured location */ | 306 | /* Enable pins at configured location */ |
318 | efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | 307 | efm32_uart_write32(efm_port, |
308 | UARTn_ROUTE_LOCATION(efm_port->pdata.location) | | ||
309 | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, | ||
319 | UARTn_ROUTE); | 310 | UARTn_ROUTE); |
320 | 311 | ||
321 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, | 312 | ret = request_irq(port->irq, efm32_uart_rxirq, 0, |
@@ -674,11 +665,24 @@ static int efm32_uart_probe_dt(struct platform_device *pdev, | |||
674 | struct efm32_uart_port *efm_port) | 665 | struct efm32_uart_port *efm_port) |
675 | { | 666 | { |
676 | struct device_node *np = pdev->dev.of_node; | 667 | struct device_node *np = pdev->dev.of_node; |
668 | u32 location; | ||
677 | int ret; | 669 | int ret; |
678 | 670 | ||
679 | if (!np) | 671 | if (!np) |
680 | return 1; | 672 | return 1; |
681 | 673 | ||
674 | ret = of_property_read_u32(np, "location", &location); | ||
675 | if (!ret) { | ||
676 | if (location > 5) { | ||
677 | dev_err(&pdev->dev, "invalid location\n"); | ||
678 | return -EINVAL; | ||
679 | } | ||
680 | efm_debug(efm_port, "using location %u\n", location); | ||
681 | efm_port->pdata.location = location; | ||
682 | } else { | ||
683 | efm_debug(efm_port, "fall back to location 0\n"); | ||
684 | } | ||
685 | |||
682 | ret = of_alias_get_id(np, "serial"); | 686 | ret = of_alias_get_id(np, "serial"); |
683 | if (ret < 0) { | 687 | if (ret < 0) { |
684 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); | 688 | dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); |
@@ -738,10 +742,16 @@ static int efm32_uart_probe(struct platform_device *pdev) | |||
738 | efm_port->port.flags = UPF_BOOT_AUTOCONF; | 742 | efm_port->port.flags = UPF_BOOT_AUTOCONF; |
739 | 743 | ||
740 | ret = efm32_uart_probe_dt(pdev, efm_port); | 744 | ret = efm32_uart_probe_dt(pdev, efm_port); |
741 | if (ret > 0) | 745 | if (ret > 0) { |
742 | /* not created by device tree */ | 746 | /* not created by device tree */ |
747 | const struct efm32_uart_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
748 | |||
743 | efm_port->port.line = pdev->id; | 749 | efm_port->port.line = pdev->id; |
744 | 750 | ||
751 | if (pdata) | ||
752 | efm_port->pdata = *pdata; | ||
753 | } | ||
754 | |||
745 | if (efm_port->port.line >= 0 && | 755 | if (efm_port->port.line >= 0 && |
746 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) | 756 | efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) |
747 | efm32_uart_ports[efm_port->port.line] = efm_port; | 757 | efm32_uart_ports[efm_port->port.line] = efm_port; |
diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index 72b6334bcf1a..bc9e6b017b05 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c | |||
@@ -734,7 +734,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
734 | static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | 734 | static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) |
735 | { | 735 | { |
736 | short int count, rcv_buff; | 736 | short int count, rcv_buff; |
737 | struct tty_struct *tty = icom_port->uart_port.state->port.tty; | 737 | struct tty_port *port = &icom_port->uart_port.state->port; |
738 | unsigned short int status; | 738 | unsigned short int status; |
739 | struct uart_icount *icount; | 739 | struct uart_icount *icount; |
740 | unsigned long offset; | 740 | unsigned long offset; |
@@ -761,7 +761,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
761 | /* Block copy all but the last byte as this may have status */ | 761 | /* Block copy all but the last byte as this may have status */ |
762 | if (count > 0) { | 762 | if (count > 0) { |
763 | first = icom_port->recv_buf[offset]; | 763 | first = icom_port->recv_buf[offset]; |
764 | tty_insert_flip_string(tty, icom_port->recv_buf + offset, count - 1); | 764 | tty_insert_flip_string(port, icom_port->recv_buf + offset, count - 1); |
765 | } | 765 | } |
766 | 766 | ||
767 | icount = &icom_port->uart_port.icount; | 767 | icount = &icom_port->uart_port.icount; |
@@ -812,7 +812,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
812 | 812 | ||
813 | } | 813 | } |
814 | 814 | ||
815 | tty_insert_flip_char(tty, *(icom_port->recv_buf + offset + count - 1), flag); | 815 | tty_insert_flip_char(port, *(icom_port->recv_buf + offset + count - 1), flag); |
816 | 816 | ||
817 | if (status & SA_FLAGS_OVERRUN) | 817 | if (status & SA_FLAGS_OVERRUN) |
818 | /* | 818 | /* |
@@ -820,7 +820,7 @@ static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port) | |||
820 | * reported immediately, and doesn't | 820 | * reported immediately, and doesn't |
821 | * affect the current character | 821 | * affect the current character |
822 | */ | 822 | */ |
823 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 823 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
824 | ignore_char: | 824 | ignore_char: |
825 | icom_port->statStg->rcv[rcv_buff].flags = 0; | 825 | icom_port->statStg->rcv[rcv_buff].flags = 0; |
826 | icom_port->statStg->rcv[rcv_buff].leLength = 0; | 826 | icom_port->statStg->rcv[rcv_buff].leLength = 0; |
@@ -834,7 +834,7 @@ ignore_char: | |||
834 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); | 834 | status = cpu_to_le16(icom_port->statStg->rcv[rcv_buff].flags); |
835 | } | 835 | } |
836 | icom_port->next_rcv = rcv_buff; | 836 | icom_port->next_rcv = rcv_buff; |
837 | tty_flip_buffer_push(tty); | 837 | tty_flip_buffer_push(port); |
838 | } | 838 | } |
839 | 839 | ||
840 | static void process_interrupt(u16 port_int_reg, | 840 | static void process_interrupt(u16 port_int_reg, |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 8cb6d8d66a13..68d7ce997ede 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -481,7 +481,6 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev) | |||
481 | unsigned char *tx_buffer; | 481 | unsigned char *tx_buffer; |
482 | 482 | ||
483 | tx_buffer = ifx_dev->tx_buffer; | 483 | tx_buffer = ifx_dev->tx_buffer; |
484 | memset(tx_buffer, 0, IFX_SPI_TRANSFER_SIZE); | ||
485 | 484 | ||
486 | /* make room for required SPI header */ | 485 | /* make room for required SPI header */ |
487 | tx_buffer += IFX_SPI_HEADER_OVERHEAD; | 486 | tx_buffer += IFX_SPI_HEADER_OVERHEAD; |
@@ -615,7 +614,7 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty) | |||
615 | tty->driver_data = ifx_dev; | 614 | tty->driver_data = ifx_dev; |
616 | 615 | ||
617 | /* allows flip string push from int context */ | 616 | /* allows flip string push from int context */ |
618 | tty->low_latency = 1; | 617 | port->low_latency = 1; |
619 | 618 | ||
620 | /* set flag to allows data transfer */ | 619 | /* set flag to allows data transfer */ |
621 | set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); | 620 | set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); |
@@ -670,12 +669,8 @@ static const struct tty_operations ifx_spi_serial_ops = { | |||
670 | static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, | 669 | static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev, |
671 | unsigned char *chars, size_t size) | 670 | unsigned char *chars, size_t size) |
672 | { | 671 | { |
673 | struct tty_struct *tty = tty_port_tty_get(&ifx_dev->tty_port); | 672 | tty_insert_flip_string(&ifx_dev->tty_port, chars, size); |
674 | if (!tty) | 673 | tty_flip_buffer_push(&ifx_dev->tty_port); |
675 | return; | ||
676 | tty_insert_flip_string(tty, chars, size); | ||
677 | tty_flip_buffer_push(tty); | ||
678 | tty_kref_put(tty); | ||
679 | } | 674 | } |
680 | 675 | ||
681 | /** | 676 | /** |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 59819121fe9b..147c9e193595 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -48,8 +48,8 @@ | |||
48 | #include <linux/of.h> | 48 | #include <linux/of.h> |
49 | #include <linux/of_device.h> | 49 | #include <linux/of_device.h> |
50 | #include <linux/pinctrl/consumer.h> | 50 | #include <linux/pinctrl/consumer.h> |
51 | #include <linux/io.h> | ||
51 | 52 | ||
52 | #include <asm/io.h> | ||
53 | #include <asm/irq.h> | 53 | #include <asm/irq.h> |
54 | #include <linux/platform_data/serial-imx.h> | 54 | #include <linux/platform_data/serial-imx.h> |
55 | 55 | ||
@@ -73,102 +73,102 @@ | |||
73 | #define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/ | 73 | #define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/ |
74 | 74 | ||
75 | /* UART Control Register Bit Fields.*/ | 75 | /* UART Control Register Bit Fields.*/ |
76 | #define URXD_CHARRDY (1<<15) | 76 | #define URXD_CHARRDY (1<<15) |
77 | #define URXD_ERR (1<<14) | 77 | #define URXD_ERR (1<<14) |
78 | #define URXD_OVRRUN (1<<13) | 78 | #define URXD_OVRRUN (1<<13) |
79 | #define URXD_FRMERR (1<<12) | 79 | #define URXD_FRMERR (1<<12) |
80 | #define URXD_BRK (1<<11) | 80 | #define URXD_BRK (1<<11) |
81 | #define URXD_PRERR (1<<10) | 81 | #define URXD_PRERR (1<<10) |
82 | #define UCR1_ADEN (1<<15) /* Auto detect interrupt */ | 82 | #define UCR1_ADEN (1<<15) /* Auto detect interrupt */ |
83 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ | 83 | #define UCR1_ADBR (1<<14) /* Auto detect baud rate */ |
84 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ | 84 | #define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ |
85 | #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ | 85 | #define UCR1_IDEN (1<<12) /* Idle condition interrupt */ |
86 | #define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ | 86 | #define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ |
87 | #define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ | 87 | #define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ |
88 | #define UCR1_IREN (1<<7) /* Infrared interface enable */ | 88 | #define UCR1_IREN (1<<7) /* Infrared interface enable */ |
89 | #define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ | 89 | #define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ |
90 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ | 90 | #define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ |
91 | #define UCR1_SNDBRK (1<<4) /* Send break */ | 91 | #define UCR1_SNDBRK (1<<4) /* Send break */ |
92 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ | 92 | #define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ |
93 | #define IMX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, i.mx1 only */ | 93 | #define IMX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, i.mx1 only */ |
94 | #define UCR1_DOZE (1<<1) /* Doze */ | 94 | #define UCR1_DOZE (1<<1) /* Doze */ |
95 | #define UCR1_UARTEN (1<<0) /* UART enabled */ | 95 | #define UCR1_UARTEN (1<<0) /* UART enabled */ |
96 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ | 96 | #define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ |
97 | #define UCR2_IRTS (1<<14) /* Ignore RTS pin */ | 97 | #define UCR2_IRTS (1<<14) /* Ignore RTS pin */ |
98 | #define UCR2_CTSC (1<<13) /* CTS pin control */ | 98 | #define UCR2_CTSC (1<<13) /* CTS pin control */ |
99 | #define UCR2_CTS (1<<12) /* Clear to send */ | 99 | #define UCR2_CTS (1<<12) /* Clear to send */ |
100 | #define UCR2_ESCEN (1<<11) /* Escape enable */ | 100 | #define UCR2_ESCEN (1<<11) /* Escape enable */ |
101 | #define UCR2_PREN (1<<8) /* Parity enable */ | 101 | #define UCR2_PREN (1<<8) /* Parity enable */ |
102 | #define UCR2_PROE (1<<7) /* Parity odd/even */ | 102 | #define UCR2_PROE (1<<7) /* Parity odd/even */ |
103 | #define UCR2_STPB (1<<6) /* Stop */ | 103 | #define UCR2_STPB (1<<6) /* Stop */ |
104 | #define UCR2_WS (1<<5) /* Word size */ | 104 | #define UCR2_WS (1<<5) /* Word size */ |
105 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ | 105 | #define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ |
106 | #define UCR2_ATEN (1<<3) /* Aging Timer Enable */ | 106 | #define UCR2_ATEN (1<<3) /* Aging Timer Enable */ |
107 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ | 107 | #define UCR2_TXEN (1<<2) /* Transmitter enabled */ |
108 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ | 108 | #define UCR2_RXEN (1<<1) /* Receiver enabled */ |
109 | #define UCR2_SRST (1<<0) /* SW reset */ | 109 | #define UCR2_SRST (1<<0) /* SW reset */ |
110 | #define UCR3_DTREN (1<<13) /* DTR interrupt enable */ | 110 | #define UCR3_DTREN (1<<13) /* DTR interrupt enable */ |
111 | #define UCR3_PARERREN (1<<12) /* Parity enable */ | 111 | #define UCR3_PARERREN (1<<12) /* Parity enable */ |
112 | #define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ | 112 | #define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ |
113 | #define UCR3_DSR (1<<10) /* Data set ready */ | 113 | #define UCR3_DSR (1<<10) /* Data set ready */ |
114 | #define UCR3_DCD (1<<9) /* Data carrier detect */ | 114 | #define UCR3_DCD (1<<9) /* Data carrier detect */ |
115 | #define UCR3_RI (1<<8) /* Ring indicator */ | 115 | #define UCR3_RI (1<<8) /* Ring indicator */ |
116 | #define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */ | 116 | #define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */ |
117 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ | 117 | #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ |
118 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ | 118 | #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ |
119 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ | 119 | #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ |
120 | #define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */ | 120 | #define IMX21_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select */ |
121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ | 121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ |
122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ | 122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ |
123 | #define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ | 123 | #define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ |
124 | #define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ | 124 | #define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ |
125 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ | 125 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ |
126 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ | 126 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ |
127 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ | 127 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ |
128 | #define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ | 128 | #define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ |
129 | #define UCR4_IRSC (1<<5) /* IR special case */ | 129 | #define UCR4_IRSC (1<<5) /* IR special case */ |
130 | #define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ | 130 | #define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ |
131 | #define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ | 131 | #define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ |
132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ | 132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ |
133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ | 133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ |
134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ | 134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ |
135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ | 135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ |
136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ | 136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ |
137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) | 137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) |
138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ | 138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ |
139 | #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ | 139 | #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ |
140 | #define USR1_RTSS (1<<14) /* RTS pin status */ | 140 | #define USR1_RTSS (1<<14) /* RTS pin status */ |
141 | #define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ | 141 | #define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ |
142 | #define USR1_RTSD (1<<12) /* RTS delta */ | 142 | #define USR1_RTSD (1<<12) /* RTS delta */ |
143 | #define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ | 143 | #define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ |
144 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ | 144 | #define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ |
145 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ | 145 | #define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ |
146 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ | 146 | #define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ |
147 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ | 147 | #define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ |
148 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ | 148 | #define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ |
149 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ | 149 | #define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ |
150 | #define USR2_ADET (1<<15) /* Auto baud rate detect complete */ | 150 | #define USR2_ADET (1<<15) /* Auto baud rate detect complete */ |
151 | #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ | 151 | #define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ |
152 | #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ | 152 | #define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ |
153 | #define USR2_IDLE (1<<12) /* Idle condition */ | 153 | #define USR2_IDLE (1<<12) /* Idle condition */ |
154 | #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ | 154 | #define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ |
155 | #define USR2_WAKE (1<<7) /* Wake */ | 155 | #define USR2_WAKE (1<<7) /* Wake */ |
156 | #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ | 156 | #define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ |
157 | #define USR2_TXDC (1<<3) /* Transmitter complete */ | 157 | #define USR2_TXDC (1<<3) /* Transmitter complete */ |
158 | #define USR2_BRCD (1<<2) /* Break condition */ | 158 | #define USR2_BRCD (1<<2) /* Break condition */ |
159 | #define USR2_ORE (1<<1) /* Overrun error */ | 159 | #define USR2_ORE (1<<1) /* Overrun error */ |
160 | #define USR2_RDR (1<<0) /* Recv data ready */ | 160 | #define USR2_RDR (1<<0) /* Recv data ready */ |
161 | #define UTS_FRCPERR (1<<13) /* Force parity error */ | 161 | #define UTS_FRCPERR (1<<13) /* Force parity error */ |
162 | #define UTS_LOOP (1<<12) /* Loop tx and rx */ | 162 | #define UTS_LOOP (1<<12) /* Loop tx and rx */ |
163 | #define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ | 163 | #define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ |
164 | #define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ | 164 | #define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ |
165 | #define UTS_TXFULL (1<<4) /* TxFIFO full */ | 165 | #define UTS_TXFULL (1<<4) /* TxFIFO full */ |
166 | #define UTS_RXFULL (1<<3) /* RxFIFO full */ | 166 | #define UTS_RXFULL (1<<3) /* RxFIFO full */ |
167 | #define UTS_SOFTRST (1<<0) /* Software reset */ | 167 | #define UTS_SOFTRST (1<<0) /* Software reset */ |
168 | 168 | ||
169 | /* We've been assigned a range on the "Low-density serial ports" major */ | 169 | /* We've been assigned a range on the "Low-density serial ports" major */ |
170 | #define SERIAL_IMX_MAJOR 207 | 170 | #define SERIAL_IMX_MAJOR 207 |
171 | #define MINOR_START 16 | 171 | #define MINOR_START 16 |
172 | #define DEV_NAME "ttymxc" | 172 | #define DEV_NAME "ttymxc" |
173 | 173 | ||
174 | /* | 174 | /* |
@@ -199,7 +199,7 @@ struct imx_port { | |||
199 | struct uart_port port; | 199 | struct uart_port port; |
200 | struct timer_list timer; | 200 | struct timer_list timer; |
201 | unsigned int old_status; | 201 | unsigned int old_status; |
202 | int txirq,rxirq,rtsirq; | 202 | int txirq, rxirq, rtsirq; |
203 | unsigned int have_rtscts:1; | 203 | unsigned int have_rtscts:1; |
204 | unsigned int use_irda:1; | 204 | unsigned int use_irda:1; |
205 | unsigned int irda_inv_rx:1; | 205 | unsigned int irda_inv_rx:1; |
@@ -397,7 +397,7 @@ static void imx_stop_rx(struct uart_port *port) | |||
397 | unsigned long temp; | 397 | unsigned long temp; |
398 | 398 | ||
399 | temp = readl(sport->port.membase + UCR2); | 399 | temp = readl(sport->port.membase + UCR2); |
400 | writel(temp &~ UCR2_RXEN, sport->port.membase + UCR2); | 400 | writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2); |
401 | } | 401 | } |
402 | 402 | ||
403 | /* | 403 | /* |
@@ -490,9 +490,8 @@ static irqreturn_t imx_txint(int irq, void *dev_id) | |||
490 | struct circ_buf *xmit = &sport->port.state->xmit; | 490 | struct circ_buf *xmit = &sport->port.state->xmit; |
491 | unsigned long flags; | 491 | unsigned long flags; |
492 | 492 | ||
493 | spin_lock_irqsave(&sport->port.lock,flags); | 493 | spin_lock_irqsave(&sport->port.lock, flags); |
494 | if (sport->port.x_char) | 494 | if (sport->port.x_char) { |
495 | { | ||
496 | /* Send next char */ | 495 | /* Send next char */ |
497 | writel(sport->port.x_char, sport->port.membase + URTX0); | 496 | writel(sport->port.x_char, sport->port.membase + URTX0); |
498 | goto out; | 497 | goto out; |
@@ -509,18 +508,18 @@ static irqreturn_t imx_txint(int irq, void *dev_id) | |||
509 | uart_write_wakeup(&sport->port); | 508 | uart_write_wakeup(&sport->port); |
510 | 509 | ||
511 | out: | 510 | out: |
512 | spin_unlock_irqrestore(&sport->port.lock,flags); | 511 | spin_unlock_irqrestore(&sport->port.lock, flags); |
513 | return IRQ_HANDLED; | 512 | return IRQ_HANDLED; |
514 | } | 513 | } |
515 | 514 | ||
516 | static irqreturn_t imx_rxint(int irq, void *dev_id) | 515 | static irqreturn_t imx_rxint(int irq, void *dev_id) |
517 | { | 516 | { |
518 | struct imx_port *sport = dev_id; | 517 | struct imx_port *sport = dev_id; |
519 | unsigned int rx,flg,ignored = 0; | 518 | unsigned int rx, flg, ignored = 0; |
520 | struct tty_struct *tty = sport->port.state->port.tty; | 519 | struct tty_port *port = &sport->port.state->port; |
521 | unsigned long flags, temp; | 520 | unsigned long flags, temp; |
522 | 521 | ||
523 | spin_lock_irqsave(&sport->port.lock,flags); | 522 | spin_lock_irqsave(&sport->port.lock, flags); |
524 | 523 | ||
525 | while (readl(sport->port.membase + USR2) & USR2_RDR) { | 524 | while (readl(sport->port.membase + USR2) & USR2_RDR) { |
526 | flg = TTY_NORMAL; | 525 | flg = TTY_NORMAL; |
@@ -570,12 +569,12 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
570 | #endif | 569 | #endif |
571 | } | 570 | } |
572 | 571 | ||
573 | tty_insert_flip_char(tty, rx, flg); | 572 | tty_insert_flip_char(port, rx, flg); |
574 | } | 573 | } |
575 | 574 | ||
576 | out: | 575 | out: |
577 | spin_unlock_irqrestore(&sport->port.lock,flags); | 576 | spin_unlock_irqrestore(&sport->port.lock, flags); |
578 | tty_flip_buffer_push(tty); | 577 | tty_flip_buffer_push(port); |
579 | return IRQ_HANDLED; | 578 | return IRQ_HANDLED; |
580 | } | 579 | } |
581 | 580 | ||
@@ -654,7 +653,7 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
654 | 653 | ||
655 | temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK; | 654 | temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK; |
656 | 655 | ||
657 | if ( break_state != 0 ) | 656 | if (break_state != 0) |
658 | temp |= UCR1_SNDBRK; | 657 | temp |= UCR1_SNDBRK; |
659 | 658 | ||
660 | writel(temp, sport->port.membase + UCR1); | 659 | writel(temp, sport->port.membase + UCR1); |
@@ -696,8 +695,8 @@ static int imx_startup(struct uart_port *port) | |||
696 | temp |= UCR4_IRSC; | 695 | temp |= UCR4_IRSC; |
697 | 696 | ||
698 | /* set the trigger level for CTS */ | 697 | /* set the trigger level for CTS */ |
699 | temp &= ~(UCR4_CTSTL_MASK<< UCR4_CTSTL_SHF); | 698 | temp &= ~(UCR4_CTSTL_MASK << UCR4_CTSTL_SHF); |
700 | temp |= CTSTL<< UCR4_CTSTL_SHF; | 699 | temp |= CTSTL << UCR4_CTSTL_SHF; |
701 | 700 | ||
702 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); | 701 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); |
703 | 702 | ||
@@ -799,7 +798,7 @@ static int imx_startup(struct uart_port *port) | |||
799 | * Enable modem status interrupts | 798 | * Enable modem status interrupts |
800 | */ | 799 | */ |
801 | imx_enable_ms(&sport->port); | 800 | imx_enable_ms(&sport->port); |
802 | spin_unlock_irqrestore(&sport->port.lock,flags); | 801 | spin_unlock_irqrestore(&sport->port.lock, flags); |
803 | 802 | ||
804 | if (USE_IRDA(sport)) { | 803 | if (USE_IRDA(sport)) { |
805 | struct imxuart_platform_data *pdata; | 804 | struct imxuart_platform_data *pdata; |
@@ -909,7 +908,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
909 | ucr2 = UCR2_SRST | UCR2_IRTS; | 908 | ucr2 = UCR2_SRST | UCR2_IRTS; |
910 | 909 | ||
911 | if (termios->c_cflag & CRTSCTS) { | 910 | if (termios->c_cflag & CRTSCTS) { |
912 | if( sport->have_rtscts ) { | 911 | if (sport->have_rtscts) { |
913 | ucr2 &= ~UCR2_IRTS; | 912 | ucr2 &= ~UCR2_IRTS; |
914 | ucr2 |= UCR2_CTSC; | 913 | ucr2 |= UCR2_CTSC; |
915 | } else { | 914 | } else { |
@@ -969,12 +968,12 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
969 | writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), | 968 | writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), |
970 | sport->port.membase + UCR1); | 969 | sport->port.membase + UCR1); |
971 | 970 | ||
972 | while ( !(readl(sport->port.membase + USR2) & USR2_TXDC)) | 971 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)) |
973 | barrier(); | 972 | barrier(); |
974 | 973 | ||
975 | /* then, disable everything */ | 974 | /* then, disable everything */ |
976 | old_txrxen = readl(sport->port.membase + UCR2); | 975 | old_txrxen = readl(sport->port.membase + UCR2); |
977 | writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN), | 976 | writel(old_txrxen & ~(UCR2_TXEN | UCR2_RXEN), |
978 | sport->port.membase + UCR2); | 977 | sport->port.membase + UCR2); |
979 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); | 978 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); |
980 | 979 | ||
@@ -1212,9 +1211,15 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1212 | struct imx_port *sport = imx_ports[co->index]; | 1211 | struct imx_port *sport = imx_ports[co->index]; |
1213 | struct imx_port_ucrs old_ucr; | 1212 | struct imx_port_ucrs old_ucr; |
1214 | unsigned int ucr1; | 1213 | unsigned int ucr1; |
1215 | unsigned long flags; | 1214 | unsigned long flags = 0; |
1215 | int locked = 1; | ||
1216 | 1216 | ||
1217 | spin_lock_irqsave(&sport->port.lock, flags); | 1217 | if (sport->port.sysrq) |
1218 | locked = 0; | ||
1219 | else if (oops_in_progress) | ||
1220 | locked = spin_trylock_irqsave(&sport->port.lock, flags); | ||
1221 | else | ||
1222 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1218 | 1223 | ||
1219 | /* | 1224 | /* |
1220 | * First, save UCR1/2/3 and then disable interrupts | 1225 | * First, save UCR1/2/3 and then disable interrupts |
@@ -1241,7 +1246,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1241 | 1246 | ||
1242 | imx_port_ucrs_restore(&sport->port, &old_ucr); | 1247 | imx_port_ucrs_restore(&sport->port, &old_ucr); |
1243 | 1248 | ||
1244 | spin_unlock_irqrestore(&sport->port.lock, flags); | 1249 | if (locked) |
1250 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1245 | } | 1251 | } |
1246 | 1252 | ||
1247 | /* | 1253 | /* |
@@ -1255,7 +1261,7 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
1255 | 1261 | ||
1256 | if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) { | 1262 | if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) { |
1257 | /* ok, the port was enabled */ | 1263 | /* ok, the port was enabled */ |
1258 | unsigned int ucr2, ubir,ubmr, uartclk; | 1264 | unsigned int ucr2, ubir, ubmr, uartclk; |
1259 | unsigned int baud_raw; | 1265 | unsigned int baud_raw; |
1260 | unsigned int ucfr_rfdiv; | 1266 | unsigned int ucfr_rfdiv; |
1261 | 1267 | ||
@@ -1301,8 +1307,8 @@ imx_console_get_options(struct imx_port *sport, int *baud, | |||
1301 | *baud = (baud_raw + 50) / 100 * 100; | 1307 | *baud = (baud_raw + 50) / 100 * 100; |
1302 | } | 1308 | } |
1303 | 1309 | ||
1304 | if(*baud != baud_raw) | 1310 | if (*baud != baud_raw) |
1305 | printk(KERN_INFO "Serial: Console IMX rounded baud rate from %d to %d\n", | 1311 | pr_info("Console IMX rounded baud rate from %d to %d\n", |
1306 | baud_raw, *baud); | 1312 | baud_raw, *baud); |
1307 | } | 1313 | } |
1308 | } | 1314 | } |
@@ -1324,7 +1330,7 @@ imx_console_setup(struct console *co, char *options) | |||
1324 | if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) | 1330 | if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) |
1325 | co->index = 0; | 1331 | co->index = 0; |
1326 | sport = imx_ports[co->index]; | 1332 | sport = imx_ports[co->index]; |
1327 | if(sport == NULL) | 1333 | if (sport == NULL) |
1328 | return -ENODEV; | 1334 | return -ENODEV; |
1329 | 1335 | ||
1330 | if (options) | 1336 | if (options) |
@@ -1462,7 +1468,7 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1462 | struct resource *res; | 1468 | struct resource *res; |
1463 | struct pinctrl *pinctrl; | 1469 | struct pinctrl *pinctrl; |
1464 | 1470 | ||
1465 | sport = kzalloc(sizeof(*sport), GFP_KERNEL); | 1471 | sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); |
1466 | if (!sport) | 1472 | if (!sport) |
1467 | return -ENOMEM; | 1473 | return -ENOMEM; |
1468 | 1474 | ||
@@ -1470,19 +1476,15 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1470 | if (ret > 0) | 1476 | if (ret > 0) |
1471 | serial_imx_probe_pdata(sport, pdev); | 1477 | serial_imx_probe_pdata(sport, pdev); |
1472 | else if (ret < 0) | 1478 | else if (ret < 0) |
1473 | goto free; | 1479 | return ret; |
1474 | 1480 | ||
1475 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1481 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1476 | if (!res) { | 1482 | if (!res) |
1477 | ret = -ENODEV; | 1483 | return -ENODEV; |
1478 | goto free; | ||
1479 | } | ||
1480 | 1484 | ||
1481 | base = ioremap(res->start, PAGE_SIZE); | 1485 | base = devm_ioremap(&pdev->dev, res->start, PAGE_SIZE); |
1482 | if (!base) { | 1486 | if (!base) |
1483 | ret = -ENOMEM; | 1487 | return -ENOMEM; |
1484 | goto free; | ||
1485 | } | ||
1486 | 1488 | ||
1487 | sport->port.dev = &pdev->dev; | 1489 | sport->port.dev = &pdev->dev; |
1488 | sport->port.mapbase = res->start; | 1490 | sport->port.mapbase = res->start; |
@@ -1504,21 +1506,21 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1504 | if (IS_ERR(pinctrl)) { | 1506 | if (IS_ERR(pinctrl)) { |
1505 | ret = PTR_ERR(pinctrl); | 1507 | ret = PTR_ERR(pinctrl); |
1506 | dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); | 1508 | dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); |
1507 | goto unmap; | 1509 | return ret; |
1508 | } | 1510 | } |
1509 | 1511 | ||
1510 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1512 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
1511 | if (IS_ERR(sport->clk_ipg)) { | 1513 | if (IS_ERR(sport->clk_ipg)) { |
1512 | ret = PTR_ERR(sport->clk_ipg); | 1514 | ret = PTR_ERR(sport->clk_ipg); |
1513 | dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret); | 1515 | dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret); |
1514 | goto unmap; | 1516 | return ret; |
1515 | } | 1517 | } |
1516 | 1518 | ||
1517 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); | 1519 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); |
1518 | if (IS_ERR(sport->clk_per)) { | 1520 | if (IS_ERR(sport->clk_per)) { |
1519 | ret = PTR_ERR(sport->clk_per); | 1521 | ret = PTR_ERR(sport->clk_per); |
1520 | dev_err(&pdev->dev, "failed to get per clk: %d\n", ret); | 1522 | dev_err(&pdev->dev, "failed to get per clk: %d\n", ret); |
1521 | goto unmap; | 1523 | return ret; |
1522 | } | 1524 | } |
1523 | 1525 | ||
1524 | clk_prepare_enable(sport->clk_per); | 1526 | clk_prepare_enable(sport->clk_per); |
@@ -1547,11 +1549,6 @@ deinit: | |||
1547 | clkput: | 1549 | clkput: |
1548 | clk_disable_unprepare(sport->clk_per); | 1550 | clk_disable_unprepare(sport->clk_per); |
1549 | clk_disable_unprepare(sport->clk_ipg); | 1551 | clk_disable_unprepare(sport->clk_ipg); |
1550 | unmap: | ||
1551 | iounmap(sport->port.membase); | ||
1552 | free: | ||
1553 | kfree(sport); | ||
1554 | |||
1555 | return ret; | 1552 | return ret; |
1556 | } | 1553 | } |
1557 | 1554 | ||
@@ -1572,9 +1569,6 @@ static int serial_imx_remove(struct platform_device *pdev) | |||
1572 | if (pdata && pdata->exit) | 1569 | if (pdata && pdata->exit) |
1573 | pdata->exit(pdev); | 1570 | pdata->exit(pdev); |
1574 | 1571 | ||
1575 | iounmap(sport->port.membase); | ||
1576 | kfree(sport); | ||
1577 | |||
1578 | return 0; | 1572 | return 0; |
1579 | } | 1573 | } |
1580 | 1574 | ||
@@ -1596,7 +1590,7 @@ static int __init imx_serial_init(void) | |||
1596 | { | 1590 | { |
1597 | int ret; | 1591 | int ret; |
1598 | 1592 | ||
1599 | printk(KERN_INFO "Serial: IMX driver\n"); | 1593 | pr_info("Serial: IMX driver\n"); |
1600 | 1594 | ||
1601 | ret = uart_register_driver(&imx_reg); | 1595 | ret = uart_register_driver(&imx_reg); |
1602 | if (ret) | 1596 | if (ret) |
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index d8f1d1d54471..6e4c715c5d26 100644 --- a/drivers/tty/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c | |||
@@ -1000,7 +1000,7 @@ ioc3_change_speed(struct uart_port *the_port, | |||
1000 | 1000 | ||
1001 | the_port->ignore_status_mask = N_ALL_INPUT; | 1001 | the_port->ignore_status_mask = N_ALL_INPUT; |
1002 | 1002 | ||
1003 | state->port.tty->low_latency = 1; | 1003 | state->port.low_latency = 1; |
1004 | 1004 | ||
1005 | if (iflag & IGNPAR) | 1005 | if (iflag & IGNPAR) |
1006 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR | 1006 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR |
@@ -1393,7 +1393,6 @@ static inline int do_read(struct uart_port *the_port, char *buf, int len) | |||
1393 | */ | 1393 | */ |
1394 | static int receive_chars(struct uart_port *the_port) | 1394 | static int receive_chars(struct uart_port *the_port) |
1395 | { | 1395 | { |
1396 | struct tty_struct *tty; | ||
1397 | unsigned char ch[MAX_CHARS]; | 1396 | unsigned char ch[MAX_CHARS]; |
1398 | int read_count = 0, read_room, flip = 0; | 1397 | int read_count = 0, read_room, flip = 0; |
1399 | struct uart_state *state = the_port->state; | 1398 | struct uart_state *state = the_port->state; |
@@ -1403,25 +1402,23 @@ static int receive_chars(struct uart_port *the_port) | |||
1403 | /* Make sure all the pointers are "good" ones */ | 1402 | /* Make sure all the pointers are "good" ones */ |
1404 | if (!state) | 1403 | if (!state) |
1405 | return 0; | 1404 | return 0; |
1406 | if (!state->port.tty) | ||
1407 | return 0; | ||
1408 | 1405 | ||
1409 | if (!(port->ip_flags & INPUT_ENABLE)) | 1406 | if (!(port->ip_flags & INPUT_ENABLE)) |
1410 | return 0; | 1407 | return 0; |
1411 | 1408 | ||
1412 | spin_lock_irqsave(&the_port->lock, pflags); | 1409 | spin_lock_irqsave(&the_port->lock, pflags); |
1413 | tty = state->port.tty; | ||
1414 | 1410 | ||
1415 | read_count = do_read(the_port, ch, MAX_CHARS); | 1411 | read_count = do_read(the_port, ch, MAX_CHARS); |
1416 | if (read_count > 0) { | 1412 | if (read_count > 0) { |
1417 | flip = 1; | 1413 | flip = 1; |
1418 | read_room = tty_insert_flip_string(tty, ch, read_count); | 1414 | read_room = tty_insert_flip_string(&state->port, ch, |
1415 | read_count); | ||
1419 | the_port->icount.rx += read_count; | 1416 | the_port->icount.rx += read_count; |
1420 | } | 1417 | } |
1421 | spin_unlock_irqrestore(&the_port->lock, pflags); | 1418 | spin_unlock_irqrestore(&the_port->lock, pflags); |
1422 | 1419 | ||
1423 | if (flip) | 1420 | if (flip) |
1424 | tty_flip_buffer_push(tty); | 1421 | tty_flip_buffer_push(&state->port); |
1425 | 1422 | ||
1426 | return read_count; | 1423 | return read_count; |
1427 | } | 1424 | } |
diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index 3e7da10cebba..e2520abcb1c4 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c | |||
@@ -1740,7 +1740,7 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1740 | 1740 | ||
1741 | the_port->ignore_status_mask = N_ALL_INPUT; | 1741 | the_port->ignore_status_mask = N_ALL_INPUT; |
1742 | 1742 | ||
1743 | state->port.tty->low_latency = 1; | 1743 | state->port.low_latency = 1; |
1744 | 1744 | ||
1745 | if (iflag & IGNPAR) | 1745 | if (iflag & IGNPAR) |
1746 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR | 1746 | the_port->ignore_status_mask &= ~(N_PARITY_ERROR |
@@ -2340,7 +2340,6 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf, | |||
2340 | */ | 2340 | */ |
2341 | static void receive_chars(struct uart_port *the_port) | 2341 | static void receive_chars(struct uart_port *the_port) |
2342 | { | 2342 | { |
2343 | struct tty_struct *tty; | ||
2344 | unsigned char ch[IOC4_MAX_CHARS]; | 2343 | unsigned char ch[IOC4_MAX_CHARS]; |
2345 | int read_count, request_count = IOC4_MAX_CHARS; | 2344 | int read_count, request_count = IOC4_MAX_CHARS; |
2346 | struct uart_icount *icount; | 2345 | struct uart_icount *icount; |
@@ -2350,26 +2349,23 @@ static void receive_chars(struct uart_port *the_port) | |||
2350 | /* Make sure all the pointers are "good" ones */ | 2349 | /* Make sure all the pointers are "good" ones */ |
2351 | if (!state) | 2350 | if (!state) |
2352 | return; | 2351 | return; |
2353 | if (!state->port.tty) | ||
2354 | return; | ||
2355 | 2352 | ||
2356 | spin_lock_irqsave(&the_port->lock, pflags); | 2353 | spin_lock_irqsave(&the_port->lock, pflags); |
2357 | tty = state->port.tty; | ||
2358 | 2354 | ||
2359 | request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS); | 2355 | request_count = tty_buffer_request_room(&state->port, IOC4_MAX_CHARS); |
2360 | 2356 | ||
2361 | if (request_count > 0) { | 2357 | if (request_count > 0) { |
2362 | icount = &the_port->icount; | 2358 | icount = &the_port->icount; |
2363 | read_count = do_read(the_port, ch, request_count); | 2359 | read_count = do_read(the_port, ch, request_count); |
2364 | if (read_count > 0) { | 2360 | if (read_count > 0) { |
2365 | tty_insert_flip_string(tty, ch, read_count); | 2361 | tty_insert_flip_string(&state->port, ch, read_count); |
2366 | icount->rx += read_count; | 2362 | icount->rx += read_count; |
2367 | } | 2363 | } |
2368 | } | 2364 | } |
2369 | 2365 | ||
2370 | spin_unlock_irqrestore(&the_port->lock, pflags); | 2366 | spin_unlock_irqrestore(&the_port->lock, pflags); |
2371 | 2367 | ||
2372 | tty_flip_buffer_push(tty); | 2368 | tty_flip_buffer_push(&state->port); |
2373 | } | 2369 | } |
2374 | 2370 | ||
2375 | /** | 2371 | /** |
@@ -2883,6 +2879,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd) | |||
2883 | /* error exits that give back resources */ | 2879 | /* error exits that give back resources */ |
2884 | out5: | 2880 | out5: |
2885 | ioc4_serial_remove_one(idd); | 2881 | ioc4_serial_remove_one(idd); |
2882 | return ret; | ||
2886 | out4: | 2883 | out4: |
2887 | kfree(soft); | 2884 | kfree(soft); |
2888 | out3: | 2885 | out3: |
diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 7b1cda59ebb5..cb3c81eb0996 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c | |||
@@ -248,17 +248,12 @@ static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up, | |||
248 | #define Rx_BRK 0x0100 /* BREAK event software flag. */ | 248 | #define Rx_BRK 0x0100 /* BREAK event software flag. */ |
249 | #define Rx_SYS 0x0200 /* SysRq event software flag. */ | 249 | #define Rx_SYS 0x0200 /* SysRq event software flag. */ |
250 | 250 | ||
251 | static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | 251 | static bool ip22zilog_receive_chars(struct uart_ip22zilog_port *up, |
252 | struct zilog_channel *channel) | 252 | struct zilog_channel *channel) |
253 | { | 253 | { |
254 | struct tty_struct *tty; | ||
255 | unsigned char ch, flag; | 254 | unsigned char ch, flag; |
256 | unsigned int r1; | 255 | unsigned int r1; |
257 | 256 | bool push = up->port.state != NULL; | |
258 | tty = NULL; | ||
259 | if (up->port.state != NULL && | ||
260 | up->port.state->port.tty != NULL) | ||
261 | tty = up->port.state->port.tty; | ||
262 | 257 | ||
263 | for (;;) { | 258 | for (;;) { |
264 | ch = readb(&channel->control); | 259 | ch = readb(&channel->control); |
@@ -312,10 +307,10 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up | |||
312 | if (uart_handle_sysrq_char(&up->port, ch)) | 307 | if (uart_handle_sysrq_char(&up->port, ch)) |
313 | continue; | 308 | continue; |
314 | 309 | ||
315 | if (tty) | 310 | if (push) |
316 | uart_insert_char(&up->port, r1, Rx_OVR, ch, flag); | 311 | uart_insert_char(&up->port, r1, Rx_OVR, ch, flag); |
317 | } | 312 | } |
318 | return tty; | 313 | return push; |
319 | } | 314 | } |
320 | 315 | ||
321 | static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, | 316 | static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, |
@@ -438,21 +433,20 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
438 | while (up) { | 433 | while (up) { |
439 | struct zilog_channel *channel | 434 | struct zilog_channel *channel |
440 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | 435 | = ZILOG_CHANNEL_FROM_PORT(&up->port); |
441 | struct tty_struct *tty; | ||
442 | unsigned char r3; | 436 | unsigned char r3; |
437 | bool push = false; | ||
443 | 438 | ||
444 | spin_lock(&up->port.lock); | 439 | spin_lock(&up->port.lock); |
445 | r3 = read_zsreg(channel, R3); | 440 | r3 = read_zsreg(channel, R3); |
446 | 441 | ||
447 | /* Channel A */ | 442 | /* Channel A */ |
448 | tty = NULL; | ||
449 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 443 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
450 | writeb(RES_H_IUS, &channel->control); | 444 | writeb(RES_H_IUS, &channel->control); |
451 | ZSDELAY(); | 445 | ZSDELAY(); |
452 | ZS_WSYNC(channel); | 446 | ZS_WSYNC(channel); |
453 | 447 | ||
454 | if (r3 & CHARxIP) | 448 | if (r3 & CHARxIP) |
455 | tty = ip22zilog_receive_chars(up, channel); | 449 | push = ip22zilog_receive_chars(up, channel); |
456 | if (r3 & CHAEXT) | 450 | if (r3 & CHAEXT) |
457 | ip22zilog_status_handle(up, channel); | 451 | ip22zilog_status_handle(up, channel); |
458 | if (r3 & CHATxIP) | 452 | if (r3 & CHATxIP) |
@@ -460,22 +454,22 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
460 | } | 454 | } |
461 | spin_unlock(&up->port.lock); | 455 | spin_unlock(&up->port.lock); |
462 | 456 | ||
463 | if (tty) | 457 | if (push) |
464 | tty_flip_buffer_push(tty); | 458 | tty_flip_buffer_push(&up->port.state->port); |
465 | 459 | ||
466 | /* Channel B */ | 460 | /* Channel B */ |
467 | up = up->next; | 461 | up = up->next; |
468 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | 462 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); |
463 | push = false; | ||
469 | 464 | ||
470 | spin_lock(&up->port.lock); | 465 | spin_lock(&up->port.lock); |
471 | tty = NULL; | ||
472 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 466 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
473 | writeb(RES_H_IUS, &channel->control); | 467 | writeb(RES_H_IUS, &channel->control); |
474 | ZSDELAY(); | 468 | ZSDELAY(); |
475 | ZS_WSYNC(channel); | 469 | ZS_WSYNC(channel); |
476 | 470 | ||
477 | if (r3 & CHBRxIP) | 471 | if (r3 & CHBRxIP) |
478 | tty = ip22zilog_receive_chars(up, channel); | 472 | push = ip22zilog_receive_chars(up, channel); |
479 | if (r3 & CHBEXT) | 473 | if (r3 & CHBEXT) |
480 | ip22zilog_status_handle(up, channel); | 474 | ip22zilog_status_handle(up, channel); |
481 | if (r3 & CHBTxIP) | 475 | if (r3 & CHBTxIP) |
@@ -483,8 +477,8 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
483 | } | 477 | } |
484 | spin_unlock(&up->port.lock); | 478 | spin_unlock(&up->port.lock); |
485 | 479 | ||
486 | if (tty) | 480 | if (push) |
487 | tty_flip_buffer_push(tty); | 481 | tty_flip_buffer_push(&up->port.state->port); |
488 | 482 | ||
489 | up = up->next; | 483 | up = up->next; |
490 | } | 484 | } |
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 4c00c5550b1a..00f250ae14c5 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c | |||
@@ -521,6 +521,7 @@ void jsm_input(struct jsm_channel *ch) | |||
521 | { | 521 | { |
522 | struct jsm_board *bd; | 522 | struct jsm_board *bd; |
523 | struct tty_struct *tp; | 523 | struct tty_struct *tp; |
524 | struct tty_port *port; | ||
524 | u32 rmask; | 525 | u32 rmask; |
525 | u16 head; | 526 | u16 head; |
526 | u16 tail; | 527 | u16 tail; |
@@ -536,7 +537,8 @@ void jsm_input(struct jsm_channel *ch) | |||
536 | if (!ch) | 537 | if (!ch) |
537 | return; | 538 | return; |
538 | 539 | ||
539 | tp = ch->uart_port.state->port.tty; | 540 | port = &ch->uart_port.state->port; |
541 | tp = port->tty; | ||
540 | 542 | ||
541 | bd = ch->ch_bd; | 543 | bd = ch->ch_bd; |
542 | if(!bd) | 544 | if(!bd) |
@@ -600,7 +602,7 @@ void jsm_input(struct jsm_channel *ch) | |||
600 | return; | 602 | return; |
601 | } | 603 | } |
602 | 604 | ||
603 | len = tty_buffer_request_room(tp, data_len); | 605 | len = tty_buffer_request_room(port, data_len); |
604 | n = len; | 606 | n = len; |
605 | 607 | ||
606 | /* | 608 | /* |
@@ -629,16 +631,16 @@ void jsm_input(struct jsm_channel *ch) | |||
629 | * format it likes. | 631 | * format it likes. |
630 | */ | 632 | */ |
631 | if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) | 633 | if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) |
632 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_BREAK); | 634 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_BREAK); |
633 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) | 635 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) |
634 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY); | 636 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_PARITY); |
635 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) | 637 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) |
636 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME); | 638 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_FRAME); |
637 | else | 639 | else |
638 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL); | 640 | tty_insert_flip_char(port, *(ch->ch_rqueue +tail +i), TTY_NORMAL); |
639 | } | 641 | } |
640 | } else { | 642 | } else { |
641 | tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; | 643 | tty_insert_flip_string(port, ch->ch_rqueue + tail, s); |
642 | } | 644 | } |
643 | tail += s; | 645 | tail += s; |
644 | n -= s; | 646 | n -= s; |
@@ -652,7 +654,7 @@ void jsm_input(struct jsm_channel *ch) | |||
652 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 654 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); |
653 | 655 | ||
654 | /* Tell the tty layer its okay to "eat" the data now */ | 656 | /* Tell the tty layer its okay to "eat" the data now */ |
655 | tty_flip_buffer_push(tp); | 657 | tty_flip_buffer_push(port); |
656 | 658 | ||
657 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); | 659 | jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); |
658 | } | 660 | } |
diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 6ac2b797a764..5dafcf1c227b 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
24 | #include <linux/tty_driver.h> | 24 | #include <linux/tty_driver.h> |
25 | #include <linux/tty_flip.h> | 25 | #include <linux/tty_flip.h> |
26 | #include <linux/serial_core.h> | ||
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
27 | #include <linux/hrtimer.h> | 28 | #include <linux/hrtimer.h> |
28 | #include <linux/tick.h> | 29 | #include <linux/tick.h> |
@@ -202,7 +203,6 @@ bool kgdb_nmi_poll_knock(void) | |||
202 | static void kgdb_nmi_tty_receiver(unsigned long data) | 203 | static void kgdb_nmi_tty_receiver(unsigned long data) |
203 | { | 204 | { |
204 | struct kgdb_nmi_tty_priv *priv = (void *)data; | 205 | struct kgdb_nmi_tty_priv *priv = (void *)data; |
205 | struct tty_struct *tty; | ||
206 | char ch; | 206 | char ch; |
207 | 207 | ||
208 | tasklet_schedule(&priv->tlet); | 208 | tasklet_schedule(&priv->tlet); |
@@ -210,16 +210,9 @@ static void kgdb_nmi_tty_receiver(unsigned long data) | |||
210 | if (likely(!kgdb_nmi_tty_enabled || !kfifo_len(&priv->fifo))) | 210 | if (likely(!kgdb_nmi_tty_enabled || !kfifo_len(&priv->fifo))) |
211 | return; | 211 | return; |
212 | 212 | ||
213 | /* Port is there, but tty might be hung up, check. */ | ||
214 | tty = tty_port_tty_get(kgdb_nmi_port); | ||
215 | if (!tty) | ||
216 | return; | ||
217 | |||
218 | while (kfifo_out(&priv->fifo, &ch, 1)) | 213 | while (kfifo_out(&priv->fifo, &ch, 1)) |
219 | tty_insert_flip_char(priv->port.tty, ch, TTY_NORMAL); | 214 | tty_insert_flip_char(&priv->port, ch, TTY_NORMAL); |
220 | tty_flip_buffer_push(priv->port.tty); | 215 | tty_flip_buffer_push(&priv->port); |
221 | |||
222 | tty_kref_put(tty); | ||
223 | } | 216 | } |
224 | 217 | ||
225 | static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty) | 218 | static int kgdb_nmi_tty_activate(struct tty_port *port, struct tty_struct *tty) |
diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 02da071fe1e7..15733da757c6 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c | |||
@@ -162,21 +162,16 @@ lqasc_enable_ms(struct uart_port *port) | |||
162 | static int | 162 | static int |
163 | lqasc_rx_chars(struct uart_port *port) | 163 | lqasc_rx_chars(struct uart_port *port) |
164 | { | 164 | { |
165 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 165 | struct tty_port *tport = &port->state->port; |
166 | unsigned int ch = 0, rsr = 0, fifocnt; | 166 | unsigned int ch = 0, rsr = 0, fifocnt; |
167 | 167 | ||
168 | if (!tty) { | 168 | fifocnt = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; |
169 | dev_dbg(port->dev, "%s:tty is busy now", __func__); | ||
170 | return -EBUSY; | ||
171 | } | ||
172 | fifocnt = | ||
173 | ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; | ||
174 | while (fifocnt--) { | 169 | while (fifocnt--) { |
175 | u8 flag = TTY_NORMAL; | 170 | u8 flag = TTY_NORMAL; |
176 | ch = ltq_r8(port->membase + LTQ_ASC_RBUF); | 171 | ch = ltq_r8(port->membase + LTQ_ASC_RBUF); |
177 | rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) | 172 | rsr = (ltq_r32(port->membase + LTQ_ASC_STATE) |
178 | & ASCSTATE_ANY) | UART_DUMMY_UER_RX; | 173 | & ASCSTATE_ANY) | UART_DUMMY_UER_RX; |
179 | tty_flip_buffer_push(tty); | 174 | tty_flip_buffer_push(tport); |
180 | port->icount.rx++; | 175 | port->icount.rx++; |
181 | 176 | ||
182 | /* | 177 | /* |
@@ -208,7 +203,7 @@ lqasc_rx_chars(struct uart_port *port) | |||
208 | } | 203 | } |
209 | 204 | ||
210 | if ((rsr & port->ignore_status_mask) == 0) | 205 | if ((rsr & port->ignore_status_mask) == 0) |
211 | tty_insert_flip_char(tty, ch, flag); | 206 | tty_insert_flip_char(tport, ch, flag); |
212 | 207 | ||
213 | if (rsr & ASCSTATE_ROE) | 208 | if (rsr & ASCSTATE_ROE) |
214 | /* | 209 | /* |
@@ -216,11 +211,12 @@ lqasc_rx_chars(struct uart_port *port) | |||
216 | * immediately, and doesn't affect the current | 211 | * immediately, and doesn't affect the current |
217 | * character | 212 | * character |
218 | */ | 213 | */ |
219 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 214 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
220 | } | 215 | } |
216 | |||
221 | if (ch != 0) | 217 | if (ch != 0) |
222 | tty_flip_buffer_push(tty); | 218 | tty_flip_buffer_push(tport); |
223 | tty_kref_put(tty); | 219 | |
224 | return 0; | 220 | return 0; |
225 | } | 221 | } |
226 | 222 | ||
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index 0e86bff3fe2a..dffea6b2cd7d 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c | |||
@@ -257,17 +257,8 @@ static void __serial_uart_flush(struct uart_port *port) | |||
257 | 257 | ||
258 | static void __serial_lpc32xx_rx(struct uart_port *port) | 258 | static void __serial_lpc32xx_rx(struct uart_port *port) |
259 | { | 259 | { |
260 | struct tty_port *tport = &port->state->port; | ||
260 | unsigned int tmp, flag; | 261 | unsigned int tmp, flag; |
261 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
262 | |||
263 | if (!tty) { | ||
264 | /* Discard data: no tty available */ | ||
265 | while (!(readl(LPC32XX_HSUART_FIFO(port->membase)) & | ||
266 | LPC32XX_HSU_RX_EMPTY)) | ||
267 | ; | ||
268 | |||
269 | return; | ||
270 | } | ||
271 | 262 | ||
272 | /* Read data from FIFO and push into terminal */ | 263 | /* Read data from FIFO and push into terminal */ |
273 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | 264 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); |
@@ -281,15 +272,14 @@ static void __serial_lpc32xx_rx(struct uart_port *port) | |||
281 | LPC32XX_HSUART_IIR(port->membase)); | 272 | LPC32XX_HSUART_IIR(port->membase)); |
282 | port->icount.frame++; | 273 | port->icount.frame++; |
283 | flag = TTY_FRAME; | 274 | flag = TTY_FRAME; |
284 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 275 | tty_insert_flip_char(tport, 0, TTY_FRAME); |
285 | } | 276 | } |
286 | 277 | ||
287 | tty_insert_flip_char(tty, (tmp & 0xFF), flag); | 278 | tty_insert_flip_char(tport, (tmp & 0xFF), flag); |
288 | 279 | ||
289 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | 280 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); |
290 | } | 281 | } |
291 | tty_flip_buffer_push(tty); | 282 | tty_flip_buffer_push(tport); |
292 | tty_kref_put(tty); | ||
293 | } | 283 | } |
294 | 284 | ||
295 | static void __serial_lpc32xx_tx(struct uart_port *port) | 285 | static void __serial_lpc32xx_tx(struct uart_port *port) |
@@ -332,7 +322,7 @@ exit_tx: | |||
332 | static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | 322 | static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) |
333 | { | 323 | { |
334 | struct uart_port *port = dev_id; | 324 | struct uart_port *port = dev_id; |
335 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 325 | struct tty_port *tport = &port->state->port; |
336 | u32 status; | 326 | u32 status; |
337 | 327 | ||
338 | spin_lock(&port->lock); | 328 | spin_lock(&port->lock); |
@@ -356,17 +346,14 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | |||
356 | writel(LPC32XX_HSU_RX_OE_INT, | 346 | writel(LPC32XX_HSU_RX_OE_INT, |
357 | LPC32XX_HSUART_IIR(port->membase)); | 347 | LPC32XX_HSUART_IIR(port->membase)); |
358 | port->icount.overrun++; | 348 | port->icount.overrun++; |
359 | if (tty) { | 349 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
360 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 350 | tty_schedule_flip(tport); |
361 | tty_schedule_flip(tty); | ||
362 | } | ||
363 | } | 351 | } |
364 | 352 | ||
365 | /* Data received? */ | 353 | /* Data received? */ |
366 | if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { | 354 | if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { |
367 | __serial_lpc32xx_rx(port); | 355 | __serial_lpc32xx_rx(port); |
368 | if (tty) | 356 | tty_flip_buffer_push(tport); |
369 | tty_flip_buffer_push(tty); | ||
370 | } | 357 | } |
371 | 358 | ||
372 | /* Transmit data request? */ | 359 | /* Transmit data request? */ |
@@ -376,7 +363,6 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | |||
376 | } | 363 | } |
377 | 364 | ||
378 | spin_unlock(&port->lock); | 365 | spin_unlock(&port->lock); |
379 | tty_kref_put(tty); | ||
380 | 366 | ||
381 | return IRQ_HANDLED; | 367 | return IRQ_HANDLED; |
382 | } | 368 | } |
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index b13949ad3408..bb1afa0922e1 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
@@ -300,7 +300,7 @@ static void m32r_sio_enable_ms(struct uart_port *port) | |||
300 | 300 | ||
301 | static void receive_chars(struct uart_sio_port *up, int *status) | 301 | static void receive_chars(struct uart_sio_port *up, int *status) |
302 | { | 302 | { |
303 | struct tty_struct *tty = up->port.state->port.tty; | 303 | struct tty_port *port = &up->port.state->port; |
304 | unsigned char ch; | 304 | unsigned char ch; |
305 | unsigned char flag; | 305 | unsigned char flag; |
306 | int max_count = 256; | 306 | int max_count = 256; |
@@ -355,7 +355,7 @@ static void receive_chars(struct uart_sio_port *up, int *status) | |||
355 | if (uart_handle_sysrq_char(&up->port, ch)) | 355 | if (uart_handle_sysrq_char(&up->port, ch)) |
356 | goto ignore_char; | 356 | goto ignore_char; |
357 | if ((*status & up->port.ignore_status_mask) == 0) | 357 | if ((*status & up->port.ignore_status_mask) == 0) |
358 | tty_insert_flip_char(tty, ch, flag); | 358 | tty_insert_flip_char(port, ch, flag); |
359 | 359 | ||
360 | if (*status & UART_LSR_OE) { | 360 | if (*status & UART_LSR_OE) { |
361 | /* | 361 | /* |
@@ -363,12 +363,12 @@ static void receive_chars(struct uart_sio_port *up, int *status) | |||
363 | * immediately, and doesn't affect the current | 363 | * immediately, and doesn't affect the current |
364 | * character. | 364 | * character. |
365 | */ | 365 | */ |
366 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 366 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
367 | } | 367 | } |
368 | ignore_char: | 368 | ignore_char: |
369 | *status = serial_in(up, UART_LSR); | 369 | *status = serial_in(up, UART_LSR); |
370 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 370 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
371 | tty_flip_buffer_push(tty); | 371 | tty_flip_buffer_push(port); |
372 | } | 372 | } |
373 | 373 | ||
374 | static void transmit_chars(struct uart_sio_port *up) | 374 | static void transmit_chars(struct uart_sio_port *up) |
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index dd6277eb5a38..32517d4bceab 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
@@ -310,8 +310,8 @@ static void max3100_work(struct work_struct *w) | |||
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
313 | if (rxchars > 16 && s->port.state->port.tty != NULL) { | 313 | if (rxchars > 16) { |
314 | tty_flip_buffer_push(s->port.state->port.tty); | 314 | tty_flip_buffer_push(&s->port.state->port); |
315 | rxchars = 0; | 315 | rxchars = 0; |
316 | } | 316 | } |
317 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 317 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
@@ -323,8 +323,8 @@ static void max3100_work(struct work_struct *w) | |||
323 | (!uart_circ_empty(xmit) && | 323 | (!uart_circ_empty(xmit) && |
324 | !uart_tx_stopped(&s->port)))); | 324 | !uart_tx_stopped(&s->port)))); |
325 | 325 | ||
326 | if (rxchars > 0 && s->port.state->port.tty != NULL) | 326 | if (rxchars > 0) |
327 | tty_flip_buffer_push(s->port.state->port.tty); | 327 | tty_flip_buffer_push(&s->port.state->port); |
328 | } | 328 | } |
329 | 329 | ||
330 | static irqreturn_t max3100_irq(int irqno, void *dev_id) | 330 | static irqreturn_t max3100_irq(int irqno, void *dev_id) |
@@ -529,7 +529,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios, | |||
529 | MAX3100_STATUS_OE; | 529 | MAX3100_STATUS_OE; |
530 | 530 | ||
531 | /* we are sending char from a workqueue so enable */ | 531 | /* we are sending char from a workqueue so enable */ |
532 | s->port.state->port.tty->low_latency = 1; | 532 | s->port.state->port.low_latency = 1; |
533 | 533 | ||
534 | if (s->poll_time > 0) | 534 | if (s->poll_time > 0) |
535 | del_timer_sync(&s->timer); | 535 | del_timer_sync(&s->timer); |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index a801f6872cad..0c2422cb04ea 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -460,10 +460,6 @@ static int max310x_set_ref_clk(struct max310x_port *s) | |||
460 | static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) | 460 | static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) |
461 | { | 461 | { |
462 | unsigned int sts = 0, ch = 0, flag; | 462 | unsigned int sts = 0, ch = 0, flag; |
463 | struct tty_struct *tty = tty_port_tty_get(&s->port.state->port); | ||
464 | |||
465 | if (!tty) | ||
466 | return; | ||
467 | 463 | ||
468 | if (unlikely(rxlen >= MAX310X_FIFO_SIZE)) { | 464 | if (unlikely(rxlen >= MAX310X_FIFO_SIZE)) { |
469 | dev_warn(s->port.dev, "Possible RX FIFO overrun %d\n", rxlen); | 465 | dev_warn(s->port.dev, "Possible RX FIFO overrun %d\n", rxlen); |
@@ -516,9 +512,7 @@ static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) | |||
516 | ch, flag); | 512 | ch, flag); |
517 | } | 513 | } |
518 | 514 | ||
519 | tty_flip_buffer_push(tty); | 515 | tty_flip_buffer_push(&s->port.state->port); |
520 | |||
521 | tty_kref_put(tty); | ||
522 | } | 516 | } |
523 | 517 | ||
524 | static void max310x_handle_tx(struct max310x_port *s) | 518 | static void max310x_handle_tx(struct max310x_port *s) |
diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index fcd56ab6053f..e956377a38fe 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
24 | #include <linux/serial_core.h> | 24 | #include <linux/serial_core.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/uaccess.h> | ||
26 | #include <asm/coldfire.h> | 27 | #include <asm/coldfire.h> |
27 | #include <asm/mcfsim.h> | 28 | #include <asm/mcfsim.h> |
28 | #include <asm/mcfuart.h> | 29 | #include <asm/mcfuart.h> |
@@ -55,6 +56,7 @@ struct mcf_uart { | |||
55 | struct uart_port port; | 56 | struct uart_port port; |
56 | unsigned int sigs; /* Local copy of line sigs */ | 57 | unsigned int sigs; /* Local copy of line sigs */ |
57 | unsigned char imr; /* Local IMR mirror */ | 58 | unsigned char imr; /* Local IMR mirror */ |
59 | struct serial_rs485 rs485; /* RS485 settings */ | ||
58 | }; | 60 | }; |
59 | 61 | ||
60 | /****************************************************************************/ | 62 | /****************************************************************************/ |
@@ -101,6 +103,12 @@ static void mcf_start_tx(struct uart_port *port) | |||
101 | { | 103 | { |
102 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | 104 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); |
103 | 105 | ||
106 | if (pp->rs485.flags & SER_RS485_ENABLED) { | ||
107 | /* Enable Transmitter */ | ||
108 | writeb(MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); | ||
109 | /* Manually assert RTS */ | ||
110 | writeb(MCFUART_UOP_RTS, port->membase + MCFUART_UOP1); | ||
111 | } | ||
104 | pp->imr |= MCFUART_UIR_TXREADY; | 112 | pp->imr |= MCFUART_UIR_TXREADY; |
105 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 113 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
106 | } | 114 | } |
@@ -196,6 +204,7 @@ static void mcf_shutdown(struct uart_port *port) | |||
196 | static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | 204 | static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, |
197 | struct ktermios *old) | 205 | struct ktermios *old) |
198 | { | 206 | { |
207 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
199 | unsigned long flags; | 208 | unsigned long flags; |
200 | unsigned int baud, baudclk; | 209 | unsigned int baud, baudclk; |
201 | #if defined(CONFIG_M5272) | 210 | #if defined(CONFIG_M5272) |
@@ -248,6 +257,11 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, | |||
248 | mr2 |= MCFUART_MR2_TXCTS; | 257 | mr2 |= MCFUART_MR2_TXCTS; |
249 | } | 258 | } |
250 | 259 | ||
260 | if (pp->rs485.flags & SER_RS485_ENABLED) { | ||
261 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
262 | mr2 |= MCFUART_MR2_TXRTS; | ||
263 | } | ||
264 | |||
251 | spin_lock_irqsave(&port->lock, flags); | 265 | spin_lock_irqsave(&port->lock, flags); |
252 | uart_update_timeout(port, termios->c_cflag, baud); | 266 | uart_update_timeout(port, termios->c_cflag, baud); |
253 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); | 267 | writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); |
@@ -310,7 +324,7 @@ static void mcf_rx_chars(struct mcf_uart *pp) | |||
310 | uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); | 324 | uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag); |
311 | } | 325 | } |
312 | 326 | ||
313 | tty_flip_buffer_push(port->state->port.tty); | 327 | tty_flip_buffer_push(&port->state->port); |
314 | } | 328 | } |
315 | 329 | ||
316 | /****************************************************************************/ | 330 | /****************************************************************************/ |
@@ -342,6 +356,10 @@ static void mcf_tx_chars(struct mcf_uart *pp) | |||
342 | if (xmit->head == xmit->tail) { | 356 | if (xmit->head == xmit->tail) { |
343 | pp->imr &= ~MCFUART_UIR_TXREADY; | 357 | pp->imr &= ~MCFUART_UIR_TXREADY; |
344 | writeb(pp->imr, port->membase + MCFUART_UIMR); | 358 | writeb(pp->imr, port->membase + MCFUART_UIMR); |
359 | /* Disable TX to negate RTS automatically */ | ||
360 | if (pp->rs485.flags & SER_RS485_ENABLED) | ||
361 | writeb(MCFUART_UCR_TXDISABLE, | ||
362 | port->membase + MCFUART_UCR); | ||
345 | } | 363 | } |
346 | } | 364 | } |
347 | 365 | ||
@@ -418,6 +436,58 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
418 | 436 | ||
419 | /****************************************************************************/ | 437 | /****************************************************************************/ |
420 | 438 | ||
439 | /* Enable or disable the RS485 support */ | ||
440 | static void mcf_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) | ||
441 | { | ||
442 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
443 | unsigned long flags; | ||
444 | unsigned char mr1, mr2; | ||
445 | |||
446 | spin_lock_irqsave(&port->lock, flags); | ||
447 | /* Get mode registers */ | ||
448 | mr1 = readb(port->membase + MCFUART_UMR); | ||
449 | mr2 = readb(port->membase + MCFUART_UMR); | ||
450 | if (rs485->flags & SER_RS485_ENABLED) { | ||
451 | dev_dbg(port->dev, "Setting UART to RS485\n"); | ||
452 | /* Automatically negate RTS after TX completes */ | ||
453 | mr2 |= MCFUART_MR2_TXRTS; | ||
454 | } else { | ||
455 | dev_dbg(port->dev, "Setting UART to RS232\n"); | ||
456 | mr2 &= ~MCFUART_MR2_TXRTS; | ||
457 | } | ||
458 | writeb(mr1, port->membase + MCFUART_UMR); | ||
459 | writeb(mr2, port->membase + MCFUART_UMR); | ||
460 | pp->rs485 = *rs485; | ||
461 | spin_unlock_irqrestore(&port->lock, flags); | ||
462 | } | ||
463 | |||
464 | static int mcf_ioctl(struct uart_port *port, unsigned int cmd, | ||
465 | unsigned long arg) | ||
466 | { | ||
467 | switch (cmd) { | ||
468 | case TIOCSRS485: { | ||
469 | struct serial_rs485 rs485; | ||
470 | if (copy_from_user(&rs485, (struct serial_rs485 *)arg, | ||
471 | sizeof(struct serial_rs485))) | ||
472 | return -EFAULT; | ||
473 | mcf_config_rs485(port, &rs485); | ||
474 | break; | ||
475 | } | ||
476 | case TIOCGRS485: { | ||
477 | struct mcf_uart *pp = container_of(port, struct mcf_uart, port); | ||
478 | if (copy_to_user((struct serial_rs485 *)arg, &pp->rs485, | ||
479 | sizeof(struct serial_rs485))) | ||
480 | return -EFAULT; | ||
481 | break; | ||
482 | } | ||
483 | default: | ||
484 | return -ENOIOCTLCMD; | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | /****************************************************************************/ | ||
490 | |||
421 | /* | 491 | /* |
422 | * Define the basic serial functions we support. | 492 | * Define the basic serial functions we support. |
423 | */ | 493 | */ |
@@ -438,6 +508,7 @@ static const struct uart_ops mcf_uart_ops = { | |||
438 | .release_port = mcf_release_port, | 508 | .release_port = mcf_release_port, |
439 | .config_port = mcf_config_port, | 509 | .config_port = mcf_config_port, |
440 | .verify_port = mcf_verify_port, | 510 | .verify_port = mcf_verify_port, |
511 | .ioctl = mcf_ioctl, | ||
441 | }; | 512 | }; |
442 | 513 | ||
443 | static struct mcf_uart mcf_ports[4]; | 514 | static struct mcf_uart mcf_ports[4]; |
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index 2c01344dc332..5f4765a7a5c5 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c | |||
@@ -387,12 +387,9 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
387 | struct hsu_dma_buffer *dbuf = &up->rxbuf; | 387 | struct hsu_dma_buffer *dbuf = &up->rxbuf; |
388 | struct hsu_dma_chan *chan = up->rxc; | 388 | struct hsu_dma_chan *chan = up->rxc; |
389 | struct uart_port *port = &up->port; | 389 | struct uart_port *port = &up->port; |
390 | struct tty_struct *tty = port->state->port.tty; | 390 | struct tty_port *tport = &port->state->port; |
391 | int count; | 391 | int count; |
392 | 392 | ||
393 | if (!tty) | ||
394 | return; | ||
395 | |||
396 | /* | 393 | /* |
397 | * First need to know how many is already transferred, | 394 | * First need to know how many is already transferred, |
398 | * then check if its a timeout DMA irq, and return | 395 | * then check if its a timeout DMA irq, and return |
@@ -423,7 +420,7 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
423 | * explicitly set tail to 0. So head will | 420 | * explicitly set tail to 0. So head will |
424 | * always be greater than tail. | 421 | * always be greater than tail. |
425 | */ | 422 | */ |
426 | tty_insert_flip_string(tty, dbuf->buf, count); | 423 | tty_insert_flip_string(tport, dbuf->buf, count); |
427 | port->icount.rx += count; | 424 | port->icount.rx += count; |
428 | 425 | ||
429 | dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, | 426 | dma_sync_single_for_device(up->port.dev, dbuf->dma_addr, |
@@ -437,7 +434,7 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) | |||
437 | | (0x1 << 16) | 434 | | (0x1 << 16) |
438 | | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ | 435 | | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ |
439 | ); | 436 | ); |
440 | tty_flip_buffer_push(tty); | 437 | tty_flip_buffer_push(tport); |
441 | 438 | ||
442 | chan_writel(chan, HSU_CH_CR, 0x3); | 439 | chan_writel(chan, HSU_CH_CR, 0x3); |
443 | 440 | ||
@@ -460,13 +457,9 @@ static void serial_hsu_stop_rx(struct uart_port *port) | |||
460 | 457 | ||
461 | static inline void receive_chars(struct uart_hsu_port *up, int *status) | 458 | static inline void receive_chars(struct uart_hsu_port *up, int *status) |
462 | { | 459 | { |
463 | struct tty_struct *tty = up->port.state->port.tty; | ||
464 | unsigned int ch, flag; | 460 | unsigned int ch, flag; |
465 | unsigned int max_count = 256; | 461 | unsigned int max_count = 256; |
466 | 462 | ||
467 | if (!tty) | ||
468 | return; | ||
469 | |||
470 | do { | 463 | do { |
471 | ch = serial_in(up, UART_RX); | 464 | ch = serial_in(up, UART_RX); |
472 | flag = TTY_NORMAL; | 465 | flag = TTY_NORMAL; |
@@ -522,7 +515,7 @@ static inline void receive_chars(struct uart_hsu_port *up, int *status) | |||
522 | ignore_char: | 515 | ignore_char: |
523 | *status = serial_in(up, UART_LSR); | 516 | *status = serial_in(up, UART_LSR); |
524 | } while ((*status & UART_LSR_DR) && max_count--); | 517 | } while ((*status & UART_LSR_DR) && max_count--); |
525 | tty_flip_buffer_push(tty); | 518 | tty_flip_buffer_push(&up->port.state->port); |
526 | } | 519 | } |
527 | 520 | ||
528 | static void transmit_chars(struct uart_hsu_port *up) | 521 | static void transmit_chars(struct uart_hsu_port *up) |
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 7c23c4f4c58d..c0e1fad51be7 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -941,7 +941,7 @@ static struct uart_ops mpc52xx_uart_ops = { | |||
941 | static inline int | 941 | static inline int |
942 | mpc52xx_uart_int_rx_chars(struct uart_port *port) | 942 | mpc52xx_uart_int_rx_chars(struct uart_port *port) |
943 | { | 943 | { |
944 | struct tty_struct *tty = port->state->port.tty; | 944 | struct tty_port *tport = &port->state->port; |
945 | unsigned char ch, flag; | 945 | unsigned char ch, flag; |
946 | unsigned short status; | 946 | unsigned short status; |
947 | 947 | ||
@@ -986,20 +986,20 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
986 | out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); | 986 | out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); |
987 | 987 | ||
988 | } | 988 | } |
989 | tty_insert_flip_char(tty, ch, flag); | 989 | tty_insert_flip_char(tport, ch, flag); |
990 | if (status & MPC52xx_PSC_SR_OE) { | 990 | if (status & MPC52xx_PSC_SR_OE) { |
991 | /* | 991 | /* |
992 | * Overrun is special, since it's | 992 | * Overrun is special, since it's |
993 | * reported immediately, and doesn't | 993 | * reported immediately, and doesn't |
994 | * affect the current character | 994 | * affect the current character |
995 | */ | 995 | */ |
996 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 996 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
997 | port->icount.overrun++; | 997 | port->icount.overrun++; |
998 | } | 998 | } |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | spin_unlock(&port->lock); | 1001 | spin_unlock(&port->lock); |
1002 | tty_flip_buffer_push(tty); | 1002 | tty_flip_buffer_push(tport); |
1003 | spin_lock(&port->lock); | 1003 | spin_lock(&port->lock); |
1004 | 1004 | ||
1005 | return psc_ops->raw_rx_rdy(port); | 1005 | return psc_ops->raw_rx_rdy(port); |
diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c index 6a9c6605666a..bc24f4931670 100644 --- a/drivers/tty/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c | |||
@@ -937,7 +937,7 @@ static int serial_polled; | |||
937 | static int mpsc_rx_intr(struct mpsc_port_info *pi) | 937 | static int mpsc_rx_intr(struct mpsc_port_info *pi) |
938 | { | 938 | { |
939 | struct mpsc_rx_desc *rxre; | 939 | struct mpsc_rx_desc *rxre; |
940 | struct tty_struct *tty = pi->port.state->port.tty; | 940 | struct tty_port *port = &pi->port.state->port; |
941 | u32 cmdstat, bytes_in, i; | 941 | u32 cmdstat, bytes_in, i; |
942 | int rc = 0; | 942 | int rc = 0; |
943 | u8 *bp; | 943 | u8 *bp; |
@@ -968,10 +968,9 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) | |||
968 | } | 968 | } |
969 | #endif | 969 | #endif |
970 | /* Following use of tty struct directly is deprecated */ | 970 | /* Following use of tty struct directly is deprecated */ |
971 | if (unlikely(tty_buffer_request_room(tty, bytes_in) | 971 | if (tty_buffer_request_room(port, bytes_in) < bytes_in) { |
972 | < bytes_in)) { | 972 | if (port->low_latency) |
973 | if (tty->low_latency) | 973 | tty_flip_buffer_push(port); |
974 | tty_flip_buffer_push(tty); | ||
975 | /* | 974 | /* |
976 | * If this failed then we will throw away the bytes | 975 | * If this failed then we will throw away the bytes |
977 | * but must do so to clear interrupts. | 976 | * but must do so to clear interrupts. |
@@ -1040,10 +1039,10 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi) | |||
1040 | | SDMA_DESC_CMDSTAT_FR | 1039 | | SDMA_DESC_CMDSTAT_FR |
1041 | | SDMA_DESC_CMDSTAT_OR))) | 1040 | | SDMA_DESC_CMDSTAT_OR))) |
1042 | && !(cmdstat & pi->port.ignore_status_mask)) { | 1041 | && !(cmdstat & pi->port.ignore_status_mask)) { |
1043 | tty_insert_flip_char(tty, *bp, flag); | 1042 | tty_insert_flip_char(port, *bp, flag); |
1044 | } else { | 1043 | } else { |
1045 | for (i=0; i<bytes_in; i++) | 1044 | for (i=0; i<bytes_in; i++) |
1046 | tty_insert_flip_char(tty, *bp++, TTY_NORMAL); | 1045 | tty_insert_flip_char(port, *bp++, TTY_NORMAL); |
1047 | 1046 | ||
1048 | pi->port.icount.rx += bytes_in; | 1047 | pi->port.icount.rx += bytes_in; |
1049 | } | 1048 | } |
@@ -1081,7 +1080,7 @@ next_frame: | |||
1081 | if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) | 1080 | if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0) |
1082 | mpsc_start_rx(pi); | 1081 | mpsc_start_rx(pi); |
1083 | 1082 | ||
1084 | tty_flip_buffer_push(tty); | 1083 | tty_flip_buffer_push(port); |
1085 | return rc; | 1084 | return rc; |
1086 | } | 1085 | } |
1087 | 1086 | ||
diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 58734d7e746d..f641c232beca 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c | |||
@@ -339,7 +339,7 @@ static int | |||
339 | receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | 339 | receive_chars(struct uart_max3110 *max, unsigned short *str, int len) |
340 | { | 340 | { |
341 | struct uart_port *port = &max->port; | 341 | struct uart_port *port = &max->port; |
342 | struct tty_struct *tty; | 342 | struct tty_port *tport; |
343 | char buf[M3110_RX_FIFO_DEPTH]; | 343 | char buf[M3110_RX_FIFO_DEPTH]; |
344 | int r, w, usable; | 344 | int r, w, usable; |
345 | 345 | ||
@@ -347,9 +347,7 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | |||
347 | if (!port->state) | 347 | if (!port->state) |
348 | return 0; | 348 | return 0; |
349 | 349 | ||
350 | tty = tty_port_tty_get(&port->state->port); | 350 | tport = &port->state->port; |
351 | if (!tty) | ||
352 | return 0; | ||
353 | 351 | ||
354 | for (r = 0, w = 0; r < len; r++) { | 352 | for (r = 0, w = 0; r < len; r++) { |
355 | if (str[r] & MAX3110_BREAK && | 353 | if (str[r] & MAX3110_BREAK && |
@@ -364,20 +362,17 @@ receive_chars(struct uart_max3110 *max, unsigned short *str, int len) | |||
364 | } | 362 | } |
365 | } | 363 | } |
366 | 364 | ||
367 | if (!w) { | 365 | if (!w) |
368 | tty_kref_put(tty); | ||
369 | return 0; | 366 | return 0; |
370 | } | ||
371 | 367 | ||
372 | for (r = 0; w; r += usable, w -= usable) { | 368 | for (r = 0; w; r += usable, w -= usable) { |
373 | usable = tty_buffer_request_room(tty, w); | 369 | usable = tty_buffer_request_room(tport, w); |
374 | if (usable) { | 370 | if (usable) { |
375 | tty_insert_flip_string(tty, buf + r, usable); | 371 | tty_insert_flip_string(tport, buf + r, usable); |
376 | port->icount.rx += usable; | 372 | port->icount.rx += usable; |
377 | } | 373 | } |
378 | } | 374 | } |
379 | tty_flip_buffer_push(tty); | 375 | tty_flip_buffer_push(tport); |
380 | tty_kref_put(tty); | ||
381 | 376 | ||
382 | return r; | 377 | return r; |
383 | } | 378 | } |
@@ -493,7 +488,7 @@ static int serial_m3110_startup(struct uart_port *port) | |||
493 | | WC_BAUD_DR2; | 488 | | WC_BAUD_DR2; |
494 | 489 | ||
495 | /* as we use thread to handle tx/rx, need set low latency */ | 490 | /* as we use thread to handle tx/rx, need set low latency */ |
496 | port->state->port.tty->low_latency = 1; | 491 | port->state->port.low_latency = 1; |
497 | 492 | ||
498 | if (max->irq) { | 493 | if (max->irq) { |
499 | max->read_thread = NULL; | 494 | max->read_thread = NULL; |
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 95fd39be2934..b11e99797fd8 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -91,14 +91,14 @@ static void msm_enable_ms(struct uart_port *port) | |||
91 | 91 | ||
92 | static void handle_rx_dm(struct uart_port *port, unsigned int misr) | 92 | static void handle_rx_dm(struct uart_port *port, unsigned int misr) |
93 | { | 93 | { |
94 | struct tty_struct *tty = port->state->port.tty; | 94 | struct tty_port *tport = &port->state->port; |
95 | unsigned int sr; | 95 | unsigned int sr; |
96 | int count = 0; | 96 | int count = 0; |
97 | struct msm_port *msm_port = UART_TO_MSM(port); | 97 | struct msm_port *msm_port = UART_TO_MSM(port); |
98 | 98 | ||
99 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { | 99 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { |
100 | port->icount.overrun++; | 100 | port->icount.overrun++; |
101 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 101 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
102 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); | 102 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); |
103 | } | 103 | } |
104 | 104 | ||
@@ -132,12 +132,12 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) | |||
132 | port->icount.frame++; | 132 | port->icount.frame++; |
133 | 133 | ||
134 | /* TODO: handle sysrq */ | 134 | /* TODO: handle sysrq */ |
135 | tty_insert_flip_string(tty, (char *) &c, | 135 | tty_insert_flip_string(tport, (char *)&c, |
136 | (count > 4) ? 4 : count); | 136 | (count > 4) ? 4 : count); |
137 | count -= 4; | 137 | count -= 4; |
138 | } | 138 | } |
139 | 139 | ||
140 | tty_flip_buffer_push(tty); | 140 | tty_flip_buffer_push(tport); |
141 | if (misr & (UART_IMR_RXSTALE)) | 141 | if (misr & (UART_IMR_RXSTALE)) |
142 | msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); | 142 | msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); |
143 | msm_write(port, 0xFFFFFF, UARTDM_DMRX); | 143 | msm_write(port, 0xFFFFFF, UARTDM_DMRX); |
@@ -146,7 +146,7 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr) | |||
146 | 146 | ||
147 | static void handle_rx(struct uart_port *port) | 147 | static void handle_rx(struct uart_port *port) |
148 | { | 148 | { |
149 | struct tty_struct *tty = port->state->port.tty; | 149 | struct tty_port *tport = &port->state->port; |
150 | unsigned int sr; | 150 | unsigned int sr; |
151 | 151 | ||
152 | /* | 152 | /* |
@@ -155,7 +155,7 @@ static void handle_rx(struct uart_port *port) | |||
155 | */ | 155 | */ |
156 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { | 156 | if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) { |
157 | port->icount.overrun++; | 157 | port->icount.overrun++; |
158 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 158 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
159 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); | 159 | msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR); |
160 | } | 160 | } |
161 | 161 | ||
@@ -186,10 +186,10 @@ static void handle_rx(struct uart_port *port) | |||
186 | } | 186 | } |
187 | 187 | ||
188 | if (!uart_handle_sysrq_char(port, c)) | 188 | if (!uart_handle_sysrq_char(port, c)) |
189 | tty_insert_flip_char(tty, c, flag); | 189 | tty_insert_flip_char(tport, c, flag); |
190 | } | 190 | } |
191 | 191 | ||
192 | tty_flip_buffer_push(tty); | 192 | tty_flip_buffer_push(tport); |
193 | } | 193 | } |
194 | 194 | ||
195 | static void reset_dm_count(struct uart_port *port) | 195 | static void reset_dm_count(struct uart_port *port) |
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 1fa92284ade0..4a942c78347e 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c | |||
@@ -908,6 +908,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
908 | unsigned long flags; | 908 | unsigned long flags; |
909 | unsigned int flush; | 909 | unsigned int flush; |
910 | struct tty_struct *tty; | 910 | struct tty_struct *tty; |
911 | struct tty_port *port; | ||
911 | struct uart_port *uport; | 912 | struct uart_port *uport; |
912 | struct msm_hs_port *msm_uport; | 913 | struct msm_hs_port *msm_uport; |
913 | 914 | ||
@@ -917,7 +918,8 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
917 | spin_lock_irqsave(&uport->lock, flags); | 918 | spin_lock_irqsave(&uport->lock, flags); |
918 | clk_enable(msm_uport->clk); | 919 | clk_enable(msm_uport->clk); |
919 | 920 | ||
920 | tty = uport->state->port.tty; | 921 | port = &uport->state->port; |
922 | tty = port->tty; | ||
921 | 923 | ||
922 | msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); | 924 | msm_hs_write(uport, UARTDM_CR_ADDR, STALE_EVENT_DISABLE); |
923 | 925 | ||
@@ -926,7 +928,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
926 | /* overflow is not connect to data in a FIFO */ | 928 | /* overflow is not connect to data in a FIFO */ |
927 | if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) && | 929 | if (unlikely((status & UARTDM_SR_OVERRUN_BMSK) && |
928 | (uport->read_status_mask & CREAD))) { | 930 | (uport->read_status_mask & CREAD))) { |
929 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 931 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
930 | uport->icount.buf_overrun++; | 932 | uport->icount.buf_overrun++; |
931 | error_f = 1; | 933 | error_f = 1; |
932 | } | 934 | } |
@@ -939,7 +941,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
939 | uport->icount.parity++; | 941 | uport->icount.parity++; |
940 | error_f = 1; | 942 | error_f = 1; |
941 | if (uport->ignore_status_mask & IGNPAR) | 943 | if (uport->ignore_status_mask & IGNPAR) |
942 | tty_insert_flip_char(tty, 0, TTY_PARITY); | 944 | tty_insert_flip_char(port, 0, TTY_PARITY); |
943 | } | 945 | } |
944 | 946 | ||
945 | if (error_f) | 947 | if (error_f) |
@@ -959,7 +961,7 @@ static void msm_hs_dmov_rx_callback(struct msm_dmov_cmd *cmd_ptr, | |||
959 | rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR); | 961 | rx_count = msm_hs_read(uport, UARTDM_RX_TOTAL_SNAP_ADDR); |
960 | 962 | ||
961 | if (0 != (uport->read_status_mask & CREAD)) { | 963 | if (0 != (uport->read_status_mask & CREAD)) { |
962 | retval = tty_insert_flip_string(tty, msm_uport->rx.buffer, | 964 | retval = tty_insert_flip_string(port, msm_uport->rx.buffer, |
963 | rx_count); | 965 | rx_count); |
964 | BUG_ON(retval != rx_count); | 966 | BUG_ON(retval != rx_count); |
965 | } | 967 | } |
@@ -979,9 +981,8 @@ static void msm_hs_tty_flip_buffer_work(struct work_struct *work) | |||
979 | { | 981 | { |
980 | struct msm_hs_port *msm_uport = | 982 | struct msm_hs_port *msm_uport = |
981 | container_of(work, struct msm_hs_port, rx.tty_work); | 983 | container_of(work, struct msm_hs_port, rx.tty_work); |
982 | struct tty_struct *tty = msm_uport->uport.state->port.tty; | ||
983 | 984 | ||
984 | tty_flip_buffer_push(tty); | 985 | tty_flip_buffer_push(&msm_uport->uport.state->port); |
985 | } | 986 | } |
986 | 987 | ||
987 | /* | 988 | /* |
@@ -1344,7 +1345,6 @@ static irqreturn_t msm_hs_rx_wakeup_isr(int irq, void *dev) | |||
1344 | unsigned long flags; | 1345 | unsigned long flags; |
1345 | struct msm_hs_port *msm_uport = dev; | 1346 | struct msm_hs_port *msm_uport = dev; |
1346 | struct uart_port *uport = &msm_uport->uport; | 1347 | struct uart_port *uport = &msm_uport->uport; |
1347 | struct tty_struct *tty = NULL; | ||
1348 | 1348 | ||
1349 | spin_lock_irqsave(&uport->lock, flags); | 1349 | spin_lock_irqsave(&uport->lock, flags); |
1350 | if (msm_uport->clk_state == MSM_HS_CLK_OFF) { | 1350 | if (msm_uport->clk_state == MSM_HS_CLK_OFF) { |
@@ -1361,8 +1361,7 @@ static irqreturn_t msm_hs_rx_wakeup_isr(int irq, void *dev) | |||
1361 | * optionally inject char into tty rx */ | 1361 | * optionally inject char into tty rx */ |
1362 | msm_hs_request_clock_on_locked(uport); | 1362 | msm_hs_request_clock_on_locked(uport); |
1363 | if (msm_uport->rx_wakeup.inject_rx) { | 1363 | if (msm_uport->rx_wakeup.inject_rx) { |
1364 | tty = uport->state->port.tty; | 1364 | tty_insert_flip_char(&uport->state->port, |
1365 | tty_insert_flip_char(tty, | ||
1366 | msm_uport->rx_wakeup.rx_to_inject, | 1365 | msm_uport->rx_wakeup.rx_to_inject, |
1367 | TTY_NORMAL); | 1366 | TTY_NORMAL); |
1368 | queue_work(msm_hs_workqueue, &msm_uport->rx.tty_work); | 1367 | queue_work(msm_hs_workqueue, &msm_uport->rx.tty_work); |
@@ -1400,7 +1399,7 @@ static int msm_hs_startup(struct uart_port *uport) | |||
1400 | 1399 | ||
1401 | /* do not let tty layer execute RX in global workqueue, use a | 1400 | /* do not let tty layer execute RX in global workqueue, use a |
1402 | * dedicated workqueue managed by this driver */ | 1401 | * dedicated workqueue managed by this driver */ |
1403 | uport->state->port.tty->low_latency = 1; | 1402 | uport->state->port.low_latency = 1; |
1404 | 1403 | ||
1405 | /* turn on uart clk */ | 1404 | /* turn on uart clk */ |
1406 | ret = msm_hs_init_clk_locked(uport); | 1405 | ret = msm_hs_init_clk_locked(uport); |
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index 925d1fa153db..e722ff163d91 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c | |||
@@ -70,7 +70,7 @@ static void smd_tty_notify(void *priv, unsigned event) | |||
70 | if (avail == 0) | 70 | if (avail == 0) |
71 | break; | 71 | break; |
72 | 72 | ||
73 | avail = tty_prepare_flip_string(tty, &ptr, avail); | 73 | avail = tty_prepare_flip_string(&info->port, &ptr, avail); |
74 | 74 | ||
75 | if (smd_read(info->ch, ptr, avail) != avail) { | 75 | if (smd_read(info->ch, ptr, avail) != avail) { |
76 | /* shouldn't be possible since we're in interrupt | 76 | /* shouldn't be possible since we're in interrupt |
@@ -80,7 +80,7 @@ static void smd_tty_notify(void *priv, unsigned event) | |||
80 | pr_err("OOPS - smd_tty_buffer mismatch?!"); | 80 | pr_err("OOPS - smd_tty_buffer mismatch?!"); |
81 | } | 81 | } |
82 | 82 | ||
83 | tty_flip_buffer_push(tty); | 83 | tty_flip_buffer_push(&info->port); |
84 | } | 84 | } |
85 | 85 | ||
86 | /* XXX only when writable and necessary */ | 86 | /* XXX only when writable and necessary */ |
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index e2775b6df5a5..7fd6aaaacd8e 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c | |||
@@ -242,8 +242,8 @@ static void mux_write(struct uart_port *port) | |||
242 | */ | 242 | */ |
243 | static void mux_read(struct uart_port *port) | 243 | static void mux_read(struct uart_port *port) |
244 | { | 244 | { |
245 | struct tty_port *tport = &port->state->port; | ||
245 | int data; | 246 | int data; |
246 | struct tty_struct *tty = port->state->port.tty; | ||
247 | __u32 start_count = port->icount.rx; | 247 | __u32 start_count = port->icount.rx; |
248 | 248 | ||
249 | while(1) { | 249 | while(1) { |
@@ -266,12 +266,11 @@ static void mux_read(struct uart_port *port) | |||
266 | if (uart_handle_sysrq_char(port, data & 0xffu)) | 266 | if (uart_handle_sysrq_char(port, data & 0xffu)) |
267 | continue; | 267 | continue; |
268 | 268 | ||
269 | tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL); | 269 | tty_insert_flip_char(tport, data & 0xFF, TTY_NORMAL); |
270 | } | 270 | } |
271 | 271 | ||
272 | if (start_count != port->icount.rx) { | 272 | if (start_count != port->icount.rx) |
273 | tty_flip_buffer_push(tty); | 273 | tty_flip_buffer_push(tport); |
274 | } | ||
275 | } | 274 | } |
276 | 275 | ||
277 | /** | 276 | /** |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index e55615eb34ad..d549fe1fa42a 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -364,7 +364,6 @@ out: | |||
364 | 364 | ||
365 | static void mxs_auart_rx_chars(struct mxs_auart_port *s) | 365 | static void mxs_auart_rx_chars(struct mxs_auart_port *s) |
366 | { | 366 | { |
367 | struct tty_struct *tty = s->port.state->port.tty; | ||
368 | u32 stat = 0; | 367 | u32 stat = 0; |
369 | 368 | ||
370 | for (;;) { | 369 | for (;;) { |
@@ -375,7 +374,7 @@ static void mxs_auart_rx_chars(struct mxs_auart_port *s) | |||
375 | } | 374 | } |
376 | 375 | ||
377 | writel(stat, s->port.membase + AUART_STAT); | 376 | writel(stat, s->port.membase + AUART_STAT); |
378 | tty_flip_buffer_push(tty); | 377 | tty_flip_buffer_push(&s->port.state->port); |
379 | } | 378 | } |
380 | 379 | ||
381 | static int mxs_auart_request_port(struct uart_port *u) | 380 | static int mxs_auart_request_port(struct uart_port *u) |
@@ -459,7 +458,7 @@ static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); | |||
459 | static void dma_rx_callback(void *arg) | 458 | static void dma_rx_callback(void *arg) |
460 | { | 459 | { |
461 | struct mxs_auart_port *s = (struct mxs_auart_port *) arg; | 460 | struct mxs_auart_port *s = (struct mxs_auart_port *) arg; |
462 | struct tty_struct *tty = s->port.state->port.tty; | 461 | struct tty_port *port = &s->port.state->port; |
463 | int count; | 462 | int count; |
464 | u32 stat; | 463 | u32 stat; |
465 | 464 | ||
@@ -470,10 +469,10 @@ static void dma_rx_callback(void *arg) | |||
470 | AUART_STAT_PERR | AUART_STAT_FERR); | 469 | AUART_STAT_PERR | AUART_STAT_FERR); |
471 | 470 | ||
472 | count = stat & AUART_STAT_RXCOUNT_MASK; | 471 | count = stat & AUART_STAT_RXCOUNT_MASK; |
473 | tty_insert_flip_string(tty, s->rx_dma_buf, count); | 472 | tty_insert_flip_string(port, s->rx_dma_buf, count); |
474 | 473 | ||
475 | writel(stat, s->port.membase + AUART_STAT); | 474 | writel(stat, s->port.membase + AUART_STAT); |
476 | tty_flip_buffer_push(tty); | 475 | tty_flip_buffer_push(port); |
477 | 476 | ||
478 | /* start the next DMA for RX. */ | 477 | /* start the next DMA for RX. */ |
479 | mxs_auart_dma_prep_rx(s); | 478 | mxs_auart_dma_prep_rx(s); |
@@ -552,7 +551,7 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s) | |||
552 | return 0; | 551 | return 0; |
553 | 552 | ||
554 | /* We do not get the right DMA channels. */ | 553 | /* We do not get the right DMA channels. */ |
555 | if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1) | 554 | if (s->dma_channel_rx == -1 || s->dma_channel_tx == -1) |
556 | return -EINVAL; | 555 | return -EINVAL; |
557 | 556 | ||
558 | /* init for RX */ | 557 | /* init for RX */ |
diff --git a/drivers/tty/serial/netx-serial.c b/drivers/tty/serial/netx-serial.c index d40da78e7c85..b9a40ed70be2 100644 --- a/drivers/tty/serial/netx-serial.c +++ b/drivers/tty/serial/netx-serial.c | |||
@@ -199,7 +199,6 @@ static void netx_txint(struct uart_port *port) | |||
199 | static void netx_rxint(struct uart_port *port) | 199 | static void netx_rxint(struct uart_port *port) |
200 | { | 200 | { |
201 | unsigned char rx, flg, status; | 201 | unsigned char rx, flg, status; |
202 | struct tty_struct *tty = port->state->port.tty; | ||
203 | 202 | ||
204 | while (!(readl(port->membase + UART_FR) & FR_RXFE)) { | 203 | while (!(readl(port->membase + UART_FR) & FR_RXFE)) { |
205 | rx = readl(port->membase + UART_DR); | 204 | rx = readl(port->membase + UART_DR); |
@@ -237,8 +236,7 @@ static void netx_rxint(struct uart_port *port) | |||
237 | uart_insert_char(port, status, SR_OE, rx, flg); | 236 | uart_insert_char(port, status, SR_OE, rx, flg); |
238 | } | 237 | } |
239 | 238 | ||
240 | tty_flip_buffer_push(tty); | 239 | tty_flip_buffer_push(&port->state->port); |
241 | return; | ||
242 | } | 240 | } |
243 | 241 | ||
244 | static irqreturn_t netx_int(int irq, void *dev_id) | 242 | static irqreturn_t netx_int(int irq, void *dev_id) |
diff --git a/drivers/tty/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c index dd4c31d1aee5..77287c54f331 100644 --- a/drivers/tty/serial/nwpserial.c +++ b/drivers/tty/serial/nwpserial.c | |||
@@ -128,7 +128,7 @@ static void nwpserial_config_port(struct uart_port *port, int flags) | |||
128 | static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) | 128 | static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) |
129 | { | 129 | { |
130 | struct nwpserial_port *up = dev_id; | 130 | struct nwpserial_port *up = dev_id; |
131 | struct tty_struct *tty = up->port.state->port.tty; | 131 | struct tty_port *port = &up->port.state->port; |
132 | irqreturn_t ret; | 132 | irqreturn_t ret; |
133 | unsigned int iir; | 133 | unsigned int iir; |
134 | unsigned char ch; | 134 | unsigned char ch; |
@@ -146,10 +146,10 @@ static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) | |||
146 | up->port.icount.rx++; | 146 | up->port.icount.rx++; |
147 | ch = dcr_read(up->dcr_host, UART_RX); | 147 | ch = dcr_read(up->dcr_host, UART_RX); |
148 | if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) | 148 | if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) |
149 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 149 | tty_insert_flip_char(port, ch, TTY_NORMAL); |
150 | } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); | 150 | } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); |
151 | 151 | ||
152 | tty_flip_buffer_push(tty); | 152 | tty_flip_buffer_push(port); |
153 | ret = IRQ_HANDLED; | 153 | ret = IRQ_HANDLED; |
154 | 154 | ||
155 | /* clear interrupt */ | 155 | /* clear interrupt */ |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index e7cae1c2d7d2..d5874605682b 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/serial_reg.h> | 18 | #include <linux/serial_reg.h> |
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_irq.h> | 20 | #include <linux/of_irq.h> |
21 | #include <linux/of_serial.h> | ||
22 | #include <linux/of_platform.h> | 21 | #include <linux/of_platform.h> |
23 | #include <linux/nwpserial.h> | 22 | #include <linux/nwpserial.h> |
24 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
@@ -45,8 +44,10 @@ void tegra_serial_handle_break(struct uart_port *p) | |||
45 | udelay(1); | 44 | udelay(1); |
46 | } while (1); | 45 | } while (1); |
47 | } | 46 | } |
48 | /* FIXME remove this export when tegra finishes conversion to open firmware */ | 47 | #else |
49 | EXPORT_SYMBOL_GPL(tegra_serial_handle_break); | 48 | static inline void tegra_serial_handle_break(struct uart_port *port) |
49 | { | ||
50 | } | ||
50 | #endif | 51 | #endif |
51 | 52 | ||
52 | /* | 53 | /* |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 57d6b29c039c..4dc41408ecb7 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -59,6 +59,7 @@ | |||
59 | 59 | ||
60 | /* SCR register bitmasks */ | 60 | /* SCR register bitmasks */ |
61 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) | 61 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) |
62 | #define OMAP_UART_SCR_TX_TRIG_GRANU1_MASK (1 << 6) | ||
62 | #define OMAP_UART_SCR_TX_EMPTY (1 << 3) | 63 | #define OMAP_UART_SCR_TX_EMPTY (1 << 3) |
63 | 64 | ||
64 | /* FCR register bitmasks */ | 65 | /* FCR register bitmasks */ |
@@ -232,24 +233,42 @@ static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | |||
232 | } | 233 | } |
233 | 234 | ||
234 | /* | 235 | /* |
236 | * serial_omap_baud_is_mode16 - check if baud rate is MODE16X | ||
237 | * @port: uart port info | ||
238 | * @baud: baudrate for which mode needs to be determined | ||
239 | * | ||
240 | * Returns true if baud rate is MODE16X and false if MODE13X | ||
241 | * Original table in OMAP TRM named "UART Mode Baud Rates, Divisor Values, | ||
242 | * and Error Rates" determines modes not for all common baud rates. | ||
243 | * E.g. for 1000000 baud rate mode must be 16x, but according to that | ||
244 | * table it's determined as 13x. | ||
245 | */ | ||
246 | static bool | ||
247 | serial_omap_baud_is_mode16(struct uart_port *port, unsigned int baud) | ||
248 | { | ||
249 | unsigned int n13 = port->uartclk / (13 * baud); | ||
250 | unsigned int n16 = port->uartclk / (16 * baud); | ||
251 | int baudAbsDiff13 = baud - (port->uartclk / (13 * n13)); | ||
252 | int baudAbsDiff16 = baud - (port->uartclk / (16 * n16)); | ||
253 | if(baudAbsDiff13 < 0) | ||
254 | baudAbsDiff13 = -baudAbsDiff13; | ||
255 | if(baudAbsDiff16 < 0) | ||
256 | baudAbsDiff16 = -baudAbsDiff16; | ||
257 | |||
258 | return (baudAbsDiff13 > baudAbsDiff16); | ||
259 | } | ||
260 | |||
261 | /* | ||
235 | * serial_omap_get_divisor - calculate divisor value | 262 | * serial_omap_get_divisor - calculate divisor value |
236 | * @port: uart port info | 263 | * @port: uart port info |
237 | * @baud: baudrate for which divisor needs to be calculated. | 264 | * @baud: baudrate for which divisor needs to be calculated. |
238 | * | ||
239 | * We have written our own function to get the divisor so as to support | ||
240 | * 13x mode. 3Mbps Baudrate as an different divisor. | ||
241 | * Reference OMAP TRM Chapter 17: | ||
242 | * Table 17-1. UART Mode Baud Rates, Divisor Values, and Error Rates | ||
243 | * referring to oversampling - divisor value | ||
244 | * baudrate 460,800 to 3,686,400 all have divisor 13 | ||
245 | * except 3,000,000 which has divisor value 16 | ||
246 | */ | 265 | */ |
247 | static unsigned int | 266 | static unsigned int |
248 | serial_omap_get_divisor(struct uart_port *port, unsigned int baud) | 267 | serial_omap_get_divisor(struct uart_port *port, unsigned int baud) |
249 | { | 268 | { |
250 | unsigned int divisor; | 269 | unsigned int divisor; |
251 | 270 | ||
252 | if (baud > OMAP_MODE13X_SPEED && baud != 3000000) | 271 | if (!serial_omap_baud_is_mode16(port, baud)) |
253 | divisor = 13; | 272 | divisor = 13; |
254 | else | 273 | else |
255 | divisor = 16; | 274 | divisor = 16; |
@@ -302,9 +321,6 @@ static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) | |||
302 | struct circ_buf *xmit = &up->port.state->xmit; | 321 | struct circ_buf *xmit = &up->port.state->xmit; |
303 | int count; | 322 | int count; |
304 | 323 | ||
305 | if (!(lsr & UART_LSR_THRE)) | ||
306 | return; | ||
307 | |||
308 | if (up->port.x_char) { | 324 | if (up->port.x_char) { |
309 | serial_out(up, UART_TX, up->port.x_char); | 325 | serial_out(up, UART_TX, up->port.x_char); |
310 | up->port.icount.tx++; | 326 | up->port.icount.tx++; |
@@ -483,7 +499,6 @@ static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) | |||
483 | static irqreturn_t serial_omap_irq(int irq, void *dev_id) | 499 | static irqreturn_t serial_omap_irq(int irq, void *dev_id) |
484 | { | 500 | { |
485 | struct uart_omap_port *up = dev_id; | 501 | struct uart_omap_port *up = dev_id; |
486 | struct tty_struct *tty = up->port.state->port.tty; | ||
487 | unsigned int iir, lsr; | 502 | unsigned int iir, lsr; |
488 | unsigned int type; | 503 | unsigned int type; |
489 | irqreturn_t ret = IRQ_NONE; | 504 | irqreturn_t ret = IRQ_NONE; |
@@ -530,7 +545,7 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) | |||
530 | 545 | ||
531 | spin_unlock(&up->port.lock); | 546 | spin_unlock(&up->port.lock); |
532 | 547 | ||
533 | tty_flip_buffer_push(tty); | 548 | tty_flip_buffer_push(&up->port.state->port); |
534 | 549 | ||
535 | pm_runtime_mark_last_busy(up->dev); | 550 | pm_runtime_mark_last_busy(up->dev); |
536 | pm_runtime_put_autosuspend(up->dev); | 551 | pm_runtime_put_autosuspend(up->dev); |
@@ -776,6 +791,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
776 | cval |= UART_LCR_PARITY; | 791 | cval |= UART_LCR_PARITY; |
777 | if (!(termios->c_cflag & PARODD)) | 792 | if (!(termios->c_cflag & PARODD)) |
778 | cval |= UART_LCR_EPAR; | 793 | cval |= UART_LCR_EPAR; |
794 | if (termios->c_cflag & CMSPAR) | ||
795 | cval |= UART_LCR_SPAR; | ||
779 | 796 | ||
780 | /* | 797 | /* |
781 | * Ask the core to calculate the divisor for us. | 798 | * Ask the core to calculate the divisor for us. |
@@ -845,7 +862,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
845 | serial_out(up, UART_IER, up->ier); | 862 | serial_out(up, UART_IER, up->ier); |
846 | serial_out(up, UART_LCR, cval); /* reset DLAB */ | 863 | serial_out(up, UART_LCR, cval); /* reset DLAB */ |
847 | up->lcr = cval; | 864 | up->lcr = cval; |
848 | up->scr = OMAP_UART_SCR_TX_EMPTY; | 865 | up->scr = 0; |
849 | 866 | ||
850 | /* FIFOs and DMA Settings */ | 867 | /* FIFOs and DMA Settings */ |
851 | 868 | ||
@@ -869,8 +886,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
869 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); | 886 | serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); |
870 | /* FIFO ENABLE, DMA MODE */ | 887 | /* FIFO ENABLE, DMA MODE */ |
871 | 888 | ||
872 | up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; | ||
873 | |||
874 | /* Set receive FIFO threshold to 16 characters and | 889 | /* Set receive FIFO threshold to 16 characters and |
875 | * transmit FIFO threshold to 16 spaces | 890 | * transmit FIFO threshold to 16 spaces |
876 | */ | 891 | */ |
@@ -915,7 +930,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
915 | serial_out(up, UART_EFR, up->efr); | 930 | serial_out(up, UART_EFR, up->efr); |
916 | serial_out(up, UART_LCR, cval); | 931 | serial_out(up, UART_LCR, cval); |
917 | 932 | ||
918 | if (baud > 230400 && baud != 3000000) | 933 | if (!serial_omap_baud_is_mode16(port, baud)) |
919 | up->mdr1 = UART_OMAP_MDR1_13X_MODE; | 934 | up->mdr1 = UART_OMAP_MDR1_13X_MODE; |
920 | else | 935 | else |
921 | up->mdr1 = UART_OMAP_MDR1_16X_MODE; | 936 | up->mdr1 = UART_OMAP_MDR1_16X_MODE; |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 8318925fbf6b..7a6c989924b3 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -14,18 +14,21 @@ | |||
14 | *along with this program; if not, write to the Free Software | 14 | *along with this program; if not, write to the Free Software |
15 | *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 15 | *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
16 | */ | 16 | */ |
17 | #if defined(CONFIG_SERIAL_PCH_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
18 | #define SUPPORT_SYSRQ | ||
19 | #endif | ||
17 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
18 | #include <linux/serial_reg.h> | 21 | #include <linux/serial_reg.h> |
19 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
20 | #include <linux/module.h> | 23 | #include <linux/module.h> |
21 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
25 | #include <linux/console.h> | ||
22 | #include <linux/serial_core.h> | 26 | #include <linux/serial_core.h> |
23 | #include <linux/tty.h> | 27 | #include <linux/tty.h> |
24 | #include <linux/tty_flip.h> | 28 | #include <linux/tty_flip.h> |
25 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
26 | #include <linux/io.h> | 30 | #include <linux/io.h> |
27 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
28 | #include <linux/console.h> | ||
29 | #include <linux/nmi.h> | 32 | #include <linux/nmi.h> |
30 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
31 | 34 | ||
@@ -553,12 +556,26 @@ static int pch_uart_hal_read(struct eg20t_port *priv, unsigned char *buf, | |||
553 | { | 556 | { |
554 | int i; | 557 | int i; |
555 | u8 rbr, lsr; | 558 | u8 rbr, lsr; |
559 | struct uart_port *port = &priv->port; | ||
556 | 560 | ||
557 | lsr = ioread8(priv->membase + UART_LSR); | 561 | lsr = ioread8(priv->membase + UART_LSR); |
558 | for (i = 0, lsr = ioread8(priv->membase + UART_LSR); | 562 | for (i = 0, lsr = ioread8(priv->membase + UART_LSR); |
559 | i < rx_size && lsr & UART_LSR_DR; | 563 | i < rx_size && lsr & (UART_LSR_DR | UART_LSR_BI); |
560 | lsr = ioread8(priv->membase + UART_LSR)) { | 564 | lsr = ioread8(priv->membase + UART_LSR)) { |
561 | rbr = ioread8(priv->membase + PCH_UART_RBR); | 565 | rbr = ioread8(priv->membase + PCH_UART_RBR); |
566 | |||
567 | if (lsr & UART_LSR_BI) { | ||
568 | port->icount.brk++; | ||
569 | if (uart_handle_break(port)) | ||
570 | continue; | ||
571 | } | ||
572 | #ifdef SUPPORT_SYSRQ | ||
573 | if (port->sysrq) { | ||
574 | if (uart_handle_sysrq_char(port, rbr)) | ||
575 | continue; | ||
576 | } | ||
577 | #endif | ||
578 | |||
562 | buf[i++] = rbr; | 579 | buf[i++] = rbr; |
563 | } | 580 | } |
564 | return i; | 581 | return i; |
@@ -591,19 +608,11 @@ static void pch_uart_hal_set_break(struct eg20t_port *priv, int on) | |||
591 | static int push_rx(struct eg20t_port *priv, const unsigned char *buf, | 608 | static int push_rx(struct eg20t_port *priv, const unsigned char *buf, |
592 | int size) | 609 | int size) |
593 | { | 610 | { |
594 | struct uart_port *port; | 611 | struct uart_port *port = &priv->port; |
595 | struct tty_struct *tty; | 612 | struct tty_port *tport = &port->state->port; |
596 | |||
597 | port = &priv->port; | ||
598 | tty = tty_port_tty_get(&port->state->port); | ||
599 | if (!tty) { | ||
600 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | ||
601 | return -EBUSY; | ||
602 | } | ||
603 | 613 | ||
604 | tty_insert_flip_string(tty, buf, size); | 614 | tty_insert_flip_string(tport, buf, size); |
605 | tty_flip_buffer_push(tty); | 615 | tty_flip_buffer_push(tport); |
606 | tty_kref_put(tty); | ||
607 | 616 | ||
608 | return 0; | 617 | return 0; |
609 | } | 618 | } |
@@ -629,15 +638,16 @@ static int dma_push_rx(struct eg20t_port *priv, int size) | |||
629 | struct tty_struct *tty; | 638 | struct tty_struct *tty; |
630 | int room; | 639 | int room; |
631 | struct uart_port *port = &priv->port; | 640 | struct uart_port *port = &priv->port; |
641 | struct tty_port *tport = &port->state->port; | ||
632 | 642 | ||
633 | port = &priv->port; | 643 | port = &priv->port; |
634 | tty = tty_port_tty_get(&port->state->port); | 644 | tty = tty_port_tty_get(tport); |
635 | if (!tty) { | 645 | if (!tty) { |
636 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | 646 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); |
637 | return 0; | 647 | return 0; |
638 | } | 648 | } |
639 | 649 | ||
640 | room = tty_buffer_request_room(tty, size); | 650 | room = tty_buffer_request_room(tport, size); |
641 | 651 | ||
642 | if (room < size) | 652 | if (room < size) |
643 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | 653 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", |
@@ -645,7 +655,7 @@ static int dma_push_rx(struct eg20t_port *priv, int size) | |||
645 | if (!room) | 655 | if (!room) |
646 | return room; | 656 | return room; |
647 | 657 | ||
648 | tty_insert_flip_string(tty, sg_virt(&priv->sg_rx), size); | 658 | tty_insert_flip_string(tport, sg_virt(&priv->sg_rx), size); |
649 | 659 | ||
650 | port->icount.rx += room; | 660 | port->icount.rx += room; |
651 | tty_kref_put(tty); | 661 | tty_kref_put(tty); |
@@ -743,19 +753,12 @@ static void pch_dma_rx_complete(void *arg) | |||
743 | { | 753 | { |
744 | struct eg20t_port *priv = arg; | 754 | struct eg20t_port *priv = arg; |
745 | struct uart_port *port = &priv->port; | 755 | struct uart_port *port = &priv->port; |
746 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
747 | int count; | 756 | int count; |
748 | 757 | ||
749 | if (!tty) { | ||
750 | dev_dbg(priv->port.dev, "%s:tty is busy now", __func__); | ||
751 | return; | ||
752 | } | ||
753 | |||
754 | dma_sync_sg_for_cpu(port->dev, &priv->sg_rx, 1, DMA_FROM_DEVICE); | 758 | dma_sync_sg_for_cpu(port->dev, &priv->sg_rx, 1, DMA_FROM_DEVICE); |
755 | count = dma_push_rx(priv, priv->trigger_level); | 759 | count = dma_push_rx(priv, priv->trigger_level); |
756 | if (count) | 760 | if (count) |
757 | tty_flip_buffer_push(tty); | 761 | tty_flip_buffer_push(&port->state->port); |
758 | tty_kref_put(tty); | ||
759 | async_tx_ack(priv->desc_rx); | 762 | async_tx_ack(priv->desc_rx); |
760 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | | 763 | pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT | |
761 | PCH_UART_HAL_RX_ERR_INT); | 764 | PCH_UART_HAL_RX_ERR_INT); |
@@ -1037,23 +1040,33 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) | |||
1037 | 1040 | ||
1038 | static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) | 1041 | static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) |
1039 | { | 1042 | { |
1040 | u8 fcr = ioread8(priv->membase + UART_FCR); | 1043 | struct uart_port *port = &priv->port; |
1041 | 1044 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | |
1042 | /* Reset FIFO */ | 1045 | char *error_msg[5] = {}; |
1043 | fcr |= UART_FCR_CLEAR_RCVR; | 1046 | int i = 0; |
1044 | iowrite8(fcr, priv->membase + UART_FCR); | ||
1045 | 1047 | ||
1046 | if (lsr & PCH_UART_LSR_ERR) | 1048 | if (lsr & PCH_UART_LSR_ERR) |
1047 | dev_err(&priv->pdev->dev, "Error data in FIFO\n"); | 1049 | error_msg[i++] = "Error data in FIFO\n"; |
1048 | 1050 | ||
1049 | if (lsr & UART_LSR_FE) | 1051 | if (lsr & UART_LSR_FE) { |
1050 | dev_err(&priv->pdev->dev, "Framing Error\n"); | 1052 | port->icount.frame++; |
1053 | error_msg[i++] = " Framing Error\n"; | ||
1054 | } | ||
1051 | 1055 | ||
1052 | if (lsr & UART_LSR_PE) | 1056 | if (lsr & UART_LSR_PE) { |
1053 | dev_err(&priv->pdev->dev, "Parity Error\n"); | 1057 | port->icount.parity++; |
1058 | error_msg[i++] = " Parity Error\n"; | ||
1059 | } | ||
1054 | 1060 | ||
1055 | if (lsr & UART_LSR_OE) | 1061 | if (lsr & UART_LSR_OE) { |
1056 | dev_err(&priv->pdev->dev, "Overrun Error\n"); | 1062 | port->icount.overrun++; |
1063 | error_msg[i++] = " Overrun Error\n"; | ||
1064 | } | ||
1065 | |||
1066 | if (tty == NULL) { | ||
1067 | for (i = 0; error_msg[i] != NULL; i++) | ||
1068 | dev_err(&priv->pdev->dev, error_msg[i]); | ||
1069 | } | ||
1057 | } | 1070 | } |
1058 | 1071 | ||
1059 | static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) | 1072 | static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) |
@@ -1564,7 +1577,8 @@ pch_console_write(struct console *co, const char *s, unsigned int count) | |||
1564 | 1577 | ||
1565 | local_irq_save(flags); | 1578 | local_irq_save(flags); |
1566 | if (priv->port.sysrq) { | 1579 | if (priv->port.sysrq) { |
1567 | spin_lock(&priv->lock); | 1580 | /* call to uart_handle_sysrq_char already took the priv lock */ |
1581 | priv_locked = 0; | ||
1568 | /* serial8250_handle_port() already took the port lock */ | 1582 | /* serial8250_handle_port() already took the port lock */ |
1569 | port_locked = 0; | 1583 | port_locked = 0; |
1570 | } else if (oops_in_progress) { | 1584 | } else if (oops_in_progress) { |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 333c8d012b0e..b1785f58b6e3 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -227,19 +227,19 @@ static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable) | |||
227 | write_zsreg(uap, R1, uap->curregs[1]); | 227 | write_zsreg(uap, R1, uap->curregs[1]); |
228 | } | 228 | } |
229 | 229 | ||
230 | static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | 230 | static bool pmz_receive_chars(struct uart_pmac_port *uap) |
231 | { | 231 | { |
232 | struct tty_struct *tty = NULL; | 232 | struct tty_port *port; |
233 | unsigned char ch, r1, drop, error, flag; | 233 | unsigned char ch, r1, drop, error, flag; |
234 | int loops = 0; | 234 | int loops = 0; |
235 | 235 | ||
236 | /* Sanity check, make sure the old bug is no longer happening */ | 236 | /* Sanity check, make sure the old bug is no longer happening */ |
237 | if (uap->port.state == NULL || uap->port.state->port.tty == NULL) { | 237 | if (uap->port.state == NULL) { |
238 | WARN_ON(1); | 238 | WARN_ON(1); |
239 | (void)read_zsdata(uap); | 239 | (void)read_zsdata(uap); |
240 | return NULL; | 240 | return false; |
241 | } | 241 | } |
242 | tty = uap->port.state->port.tty; | 242 | port = &uap->port.state->port; |
243 | 243 | ||
244 | while (1) { | 244 | while (1) { |
245 | error = 0; | 245 | error = 0; |
@@ -309,10 +309,10 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
309 | 309 | ||
310 | if (uap->port.ignore_status_mask == 0xff || | 310 | if (uap->port.ignore_status_mask == 0xff || |
311 | (r1 & uap->port.ignore_status_mask) == 0) { | 311 | (r1 & uap->port.ignore_status_mask) == 0) { |
312 | tty_insert_flip_char(tty, ch, flag); | 312 | tty_insert_flip_char(port, ch, flag); |
313 | } | 313 | } |
314 | if (r1 & Rx_OVR) | 314 | if (r1 & Rx_OVR) |
315 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 315 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
316 | next_char: | 316 | next_char: |
317 | /* We can get stuck in an infinite loop getting char 0 when the | 317 | /* We can get stuck in an infinite loop getting char 0 when the |
318 | * line is in a wrong HW state, we break that here. | 318 | * line is in a wrong HW state, we break that here. |
@@ -328,11 +328,11 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap) | |||
328 | break; | 328 | break; |
329 | } | 329 | } |
330 | 330 | ||
331 | return tty; | 331 | return true; |
332 | flood: | 332 | flood: |
333 | pmz_interrupt_control(uap, 0); | 333 | pmz_interrupt_control(uap, 0); |
334 | pmz_error("pmz: rx irq flood !\n"); | 334 | pmz_error("pmz: rx irq flood !\n"); |
335 | return tty; | 335 | return true; |
336 | } | 336 | } |
337 | 337 | ||
338 | static void pmz_status_handle(struct uart_pmac_port *uap) | 338 | static void pmz_status_handle(struct uart_pmac_port *uap) |
@@ -453,7 +453,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
453 | struct uart_pmac_port *uap_a; | 453 | struct uart_pmac_port *uap_a; |
454 | struct uart_pmac_port *uap_b; | 454 | struct uart_pmac_port *uap_b; |
455 | int rc = IRQ_NONE; | 455 | int rc = IRQ_NONE; |
456 | struct tty_struct *tty; | 456 | bool push; |
457 | u8 r3; | 457 | u8 r3; |
458 | 458 | ||
459 | uap_a = pmz_get_port_A(uap); | 459 | uap_a = pmz_get_port_A(uap); |
@@ -466,7 +466,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
466 | pmz_debug("irq, r3: %x\n", r3); | 466 | pmz_debug("irq, r3: %x\n", r3); |
467 | #endif | 467 | #endif |
468 | /* Channel A */ | 468 | /* Channel A */ |
469 | tty = NULL; | 469 | push = false; |
470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
471 | if (!ZS_IS_OPEN(uap_a)) { | 471 | if (!ZS_IS_OPEN(uap_a)) { |
472 | pmz_debug("ChanA interrupt while not open !\n"); | 472 | pmz_debug("ChanA interrupt while not open !\n"); |
@@ -477,21 +477,21 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
477 | if (r3 & CHAEXT) | 477 | if (r3 & CHAEXT) |
478 | pmz_status_handle(uap_a); | 478 | pmz_status_handle(uap_a); |
479 | if (r3 & CHARxIP) | 479 | if (r3 & CHARxIP) |
480 | tty = pmz_receive_chars(uap_a); | 480 | push = pmz_receive_chars(uap_a); |
481 | if (r3 & CHATxIP) | 481 | if (r3 & CHATxIP) |
482 | pmz_transmit_chars(uap_a); | 482 | pmz_transmit_chars(uap_a); |
483 | rc = IRQ_HANDLED; | 483 | rc = IRQ_HANDLED; |
484 | } | 484 | } |
485 | skip_a: | 485 | skip_a: |
486 | spin_unlock(&uap_a->port.lock); | 486 | spin_unlock(&uap_a->port.lock); |
487 | if (tty != NULL) | 487 | if (push) |
488 | tty_flip_buffer_push(tty); | 488 | tty_flip_buffer_push(&uap->port.state->port); |
489 | 489 | ||
490 | if (!uap_b) | 490 | if (!uap_b) |
491 | goto out; | 491 | goto out; |
492 | 492 | ||
493 | spin_lock(&uap_b->port.lock); | 493 | spin_lock(&uap_b->port.lock); |
494 | tty = NULL; | 494 | push = false; |
495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
496 | if (!ZS_IS_OPEN(uap_b)) { | 496 | if (!ZS_IS_OPEN(uap_b)) { |
497 | pmz_debug("ChanB interrupt while not open !\n"); | 497 | pmz_debug("ChanB interrupt while not open !\n"); |
@@ -502,15 +502,15 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
502 | if (r3 & CHBEXT) | 502 | if (r3 & CHBEXT) |
503 | pmz_status_handle(uap_b); | 503 | pmz_status_handle(uap_b); |
504 | if (r3 & CHBRxIP) | 504 | if (r3 & CHBRxIP) |
505 | tty = pmz_receive_chars(uap_b); | 505 | push = pmz_receive_chars(uap_b); |
506 | if (r3 & CHBTxIP) | 506 | if (r3 & CHBTxIP) |
507 | pmz_transmit_chars(uap_b); | 507 | pmz_transmit_chars(uap_b); |
508 | rc = IRQ_HANDLED; | 508 | rc = IRQ_HANDLED; |
509 | } | 509 | } |
510 | skip_b: | 510 | skip_b: |
511 | spin_unlock(&uap_b->port.lock); | 511 | spin_unlock(&uap_b->port.lock); |
512 | if (tty != NULL) | 512 | if (push) |
513 | tty_flip_buffer_push(tty); | 513 | tty_flip_buffer_push(&uap->port.state->port); |
514 | 514 | ||
515 | out: | 515 | out: |
516 | return rc; | 516 | return rc; |
diff --git a/drivers/tty/serial/pnx8xxx_uart.c b/drivers/tty/serial/pnx8xxx_uart.c index 0aa75a97531c..7e277a5384a7 100644 --- a/drivers/tty/serial/pnx8xxx_uart.c +++ b/drivers/tty/serial/pnx8xxx_uart.c | |||
@@ -181,7 +181,6 @@ static void pnx8xxx_enable_ms(struct uart_port *port) | |||
181 | 181 | ||
182 | static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) | 182 | static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) |
183 | { | 183 | { |
184 | struct tty_struct *tty = sport->port.state->port.tty; | ||
185 | unsigned int status, ch, flg; | 184 | unsigned int status, ch, flg; |
186 | 185 | ||
187 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | | 186 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | |
@@ -238,7 +237,7 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport) | |||
238 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | | 237 | status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) | |
239 | ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); | 238 | ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT)); |
240 | } | 239 | } |
241 | tty_flip_buffer_push(tty); | 240 | tty_flip_buffer_push(&sport->port.state->port); |
242 | } | 241 | } |
243 | 242 | ||
244 | static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) | 243 | static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport) |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 2764828251f5..05f504e0c271 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
@@ -98,7 +98,6 @@ static void serial_pxa_stop_rx(struct uart_port *port) | |||
98 | 98 | ||
99 | static inline void receive_chars(struct uart_pxa_port *up, int *status) | 99 | static inline void receive_chars(struct uart_pxa_port *up, int *status) |
100 | { | 100 | { |
101 | struct tty_struct *tty = up->port.state->port.tty; | ||
102 | unsigned int ch, flag; | 101 | unsigned int ch, flag; |
103 | int max_count = 256; | 102 | int max_count = 256; |
104 | 103 | ||
@@ -168,7 +167,7 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status) | |||
168 | ignore_char: | 167 | ignore_char: |
169 | *status = serial_in(up, UART_LSR); | 168 | *status = serial_in(up, UART_LSR); |
170 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 169 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
171 | tty_flip_buffer_push(tty); | 170 | tty_flip_buffer_push(&up->port.state->port); |
172 | 171 | ||
173 | /* work around Errata #20 according to | 172 | /* work around Errata #20 according to |
174 | * Intel(R) PXA27x Processor Family | 173 | * Intel(R) PXA27x Processor Family |
@@ -673,8 +672,7 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
673 | unsigned long flags; | 672 | unsigned long flags; |
674 | int locked = 1; | 673 | int locked = 1; |
675 | 674 | ||
676 | clk_prepare_enable(up->clk); | 675 | clk_enable(up->clk); |
677 | |||
678 | local_irq_save(flags); | 676 | local_irq_save(flags); |
679 | if (up->port.sysrq) | 677 | if (up->port.sysrq) |
680 | locked = 0; | 678 | locked = 0; |
@@ -701,8 +699,8 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
701 | if (locked) | 699 | if (locked) |
702 | spin_unlock(&up->port.lock); | 700 | spin_unlock(&up->port.lock); |
703 | local_irq_restore(flags); | 701 | local_irq_restore(flags); |
702 | clk_disable(up->clk); | ||
704 | 703 | ||
705 | clk_disable_unprepare(up->clk); | ||
706 | } | 704 | } |
707 | 705 | ||
708 | #ifdef CONFIG_CONSOLE_POLL | 706 | #ifdef CONFIG_CONSOLE_POLL |
@@ -899,6 +897,12 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
899 | goto err_free; | 897 | goto err_free; |
900 | } | 898 | } |
901 | 899 | ||
900 | ret = clk_prepare(sport->clk); | ||
901 | if (ret) { | ||
902 | clk_put(sport->clk); | ||
903 | goto err_free; | ||
904 | } | ||
905 | |||
902 | sport->port.type = PORT_PXA; | 906 | sport->port.type = PORT_PXA; |
903 | sport->port.iotype = UPIO_MEM; | 907 | sport->port.iotype = UPIO_MEM; |
904 | sport->port.mapbase = mmres->start; | 908 | sport->port.mapbase = mmres->start; |
@@ -930,6 +934,7 @@ static int serial_pxa_probe(struct platform_device *dev) | |||
930 | return 0; | 934 | return 0; |
931 | 935 | ||
932 | err_clk: | 936 | err_clk: |
937 | clk_unprepare(sport->clk); | ||
933 | clk_put(sport->clk); | 938 | clk_put(sport->clk); |
934 | err_free: | 939 | err_free: |
935 | kfree(sport); | 940 | kfree(sport); |
@@ -943,6 +948,8 @@ static int serial_pxa_remove(struct platform_device *dev) | |||
943 | platform_set_drvdata(dev, NULL); | 948 | platform_set_drvdata(dev, NULL); |
944 | 949 | ||
945 | uart_remove_one_port(&serial_pxa_reg, &sport->port); | 950 | uart_remove_one_port(&serial_pxa_reg, &sport->port); |
951 | |||
952 | clk_unprepare(sport->clk); | ||
946 | clk_put(sport->clk); | 953 | clk_put(sport->clk); |
947 | kfree(sport); | 954 | kfree(sport); |
948 | 955 | ||
diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c new file mode 100644 index 000000000000..a314a943f124 --- /dev/null +++ b/drivers/tty/serial/rp2.c | |||
@@ -0,0 +1,885 @@ | |||
1 | /* | ||
2 | * Driver for Comtrol RocketPort EXPRESS/INFINITY cards | ||
3 | * | ||
4 | * Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com> | ||
5 | * | ||
6 | * Inspired by, and loosely based on: | ||
7 | * | ||
8 | * ar933x_uart.c | ||
9 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
10 | * | ||
11 | * rocketport_infinity_express-linux-1.20.tar.gz | ||
12 | * Copyright (C) 2004-2011 Comtrol, Inc. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify it | ||
15 | * under the terms of the GNU General Public License version 2 as published | ||
16 | * by the Free Software Foundation. | ||
17 | */ | ||
18 | |||
19 | #include <linux/bitops.h> | ||
20 | #include <linux/compiler.h> | ||
21 | #include <linux/completion.h> | ||
22 | #include <linux/console.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/firmware.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/log2.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/serial_core.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/sysrq.h> | ||
37 | #include <linux/tty.h> | ||
38 | #include <linux/tty_flip.h> | ||
39 | #include <linux/types.h> | ||
40 | |||
41 | #define DRV_NAME "rp2" | ||
42 | |||
43 | #define RP2_FW_NAME "rp2.fw" | ||
44 | #define RP2_UCODE_BYTES 0x3f | ||
45 | |||
46 | #define PORTS_PER_ASIC 16 | ||
47 | #define ALL_PORTS_MASK (BIT(PORTS_PER_ASIC) - 1) | ||
48 | |||
49 | #define UART_CLOCK 44236800 | ||
50 | #define DEFAULT_BAUD_DIV (UART_CLOCK / (9600 * 16)) | ||
51 | #define FIFO_SIZE 512 | ||
52 | |||
53 | /* BAR0 registers */ | ||
54 | #define RP2_FPGA_CTL0 0x110 | ||
55 | #define RP2_FPGA_CTL1 0x11c | ||
56 | #define RP2_IRQ_MASK 0x1ec | ||
57 | #define RP2_IRQ_MASK_EN_m BIT(0) | ||
58 | #define RP2_IRQ_STATUS 0x1f0 | ||
59 | |||
60 | /* BAR1 registers */ | ||
61 | #define RP2_ASIC_SPACING 0x1000 | ||
62 | #define RP2_ASIC_OFFSET(i) ((i) << ilog2(RP2_ASIC_SPACING)) | ||
63 | |||
64 | #define RP2_PORT_BASE 0x000 | ||
65 | #define RP2_PORT_SPACING 0x040 | ||
66 | |||
67 | #define RP2_UCODE_BASE 0x400 | ||
68 | #define RP2_UCODE_SPACING 0x80 | ||
69 | |||
70 | #define RP2_CLK_PRESCALER 0xc00 | ||
71 | #define RP2_CH_IRQ_STAT 0xc04 | ||
72 | #define RP2_CH_IRQ_MASK 0xc08 | ||
73 | #define RP2_ASIC_IRQ 0xd00 | ||
74 | #define RP2_ASIC_IRQ_EN_m BIT(20) | ||
75 | #define RP2_GLOBAL_CMD 0xd0c | ||
76 | #define RP2_ASIC_CFG 0xd04 | ||
77 | |||
78 | /* port registers */ | ||
79 | #define RP2_DATA_DWORD 0x000 | ||
80 | |||
81 | #define RP2_DATA_BYTE 0x008 | ||
82 | #define RP2_DATA_BYTE_ERR_PARITY_m BIT(8) | ||
83 | #define RP2_DATA_BYTE_ERR_OVERRUN_m BIT(9) | ||
84 | #define RP2_DATA_BYTE_ERR_FRAMING_m BIT(10) | ||
85 | #define RP2_DATA_BYTE_BREAK_m BIT(11) | ||
86 | |||
87 | /* This lets uart_insert_char() drop bytes received on a !CREAD port */ | ||
88 | #define RP2_DUMMY_READ BIT(16) | ||
89 | |||
90 | #define RP2_DATA_BYTE_EXCEPTION_MASK (RP2_DATA_BYTE_ERR_PARITY_m | \ | ||
91 | RP2_DATA_BYTE_ERR_OVERRUN_m | \ | ||
92 | RP2_DATA_BYTE_ERR_FRAMING_m | \ | ||
93 | RP2_DATA_BYTE_BREAK_m) | ||
94 | |||
95 | #define RP2_RX_FIFO_COUNT 0x00c | ||
96 | #define RP2_TX_FIFO_COUNT 0x00e | ||
97 | |||
98 | #define RP2_CHAN_STAT 0x010 | ||
99 | #define RP2_CHAN_STAT_RXDATA_m BIT(0) | ||
100 | #define RP2_CHAN_STAT_DCD_m BIT(3) | ||
101 | #define RP2_CHAN_STAT_DSR_m BIT(4) | ||
102 | #define RP2_CHAN_STAT_CTS_m BIT(5) | ||
103 | #define RP2_CHAN_STAT_RI_m BIT(6) | ||
104 | #define RP2_CHAN_STAT_OVERRUN_m BIT(13) | ||
105 | #define RP2_CHAN_STAT_DSR_CHANGED_m BIT(16) | ||
106 | #define RP2_CHAN_STAT_CTS_CHANGED_m BIT(17) | ||
107 | #define RP2_CHAN_STAT_CD_CHANGED_m BIT(18) | ||
108 | #define RP2_CHAN_STAT_RI_CHANGED_m BIT(22) | ||
109 | #define RP2_CHAN_STAT_TXEMPTY_m BIT(25) | ||
110 | |||
111 | #define RP2_CHAN_STAT_MS_CHANGED_MASK (RP2_CHAN_STAT_DSR_CHANGED_m | \ | ||
112 | RP2_CHAN_STAT_CTS_CHANGED_m | \ | ||
113 | RP2_CHAN_STAT_CD_CHANGED_m | \ | ||
114 | RP2_CHAN_STAT_RI_CHANGED_m) | ||
115 | |||
116 | #define RP2_TXRX_CTL 0x014 | ||
117 | #define RP2_TXRX_CTL_MSRIRQ_m BIT(0) | ||
118 | #define RP2_TXRX_CTL_RXIRQ_m BIT(2) | ||
119 | #define RP2_TXRX_CTL_RX_TRIG_s 3 | ||
120 | #define RP2_TXRX_CTL_RX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
121 | #define RP2_TXRX_CTL_RX_TRIG_1 (0x1 << RP2_TXRX_CTL_RX_TRIG_s) | ||
122 | #define RP2_TXRX_CTL_RX_TRIG_256 (0x2 << RP2_TXRX_CTL_RX_TRIG_s) | ||
123 | #define RP2_TXRX_CTL_RX_TRIG_448 (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
124 | #define RP2_TXRX_CTL_RX_EN_m BIT(5) | ||
125 | #define RP2_TXRX_CTL_RTSFLOW_m BIT(6) | ||
126 | #define RP2_TXRX_CTL_DTRFLOW_m BIT(7) | ||
127 | #define RP2_TXRX_CTL_TX_TRIG_s 16 | ||
128 | #define RP2_TXRX_CTL_TX_TRIG_m (0x3 << RP2_TXRX_CTL_RX_TRIG_s) | ||
129 | #define RP2_TXRX_CTL_DSRFLOW_m BIT(18) | ||
130 | #define RP2_TXRX_CTL_TXIRQ_m BIT(19) | ||
131 | #define RP2_TXRX_CTL_CTSFLOW_m BIT(23) | ||
132 | #define RP2_TXRX_CTL_TX_EN_m BIT(24) | ||
133 | #define RP2_TXRX_CTL_RTS_m BIT(25) | ||
134 | #define RP2_TXRX_CTL_DTR_m BIT(26) | ||
135 | #define RP2_TXRX_CTL_LOOP_m BIT(27) | ||
136 | #define RP2_TXRX_CTL_BREAK_m BIT(28) | ||
137 | #define RP2_TXRX_CTL_CMSPAR_m BIT(29) | ||
138 | #define RP2_TXRX_CTL_nPARODD_m BIT(30) | ||
139 | #define RP2_TXRX_CTL_PARENB_m BIT(31) | ||
140 | |||
141 | #define RP2_UART_CTL 0x018 | ||
142 | #define RP2_UART_CTL_MODE_s 0 | ||
143 | #define RP2_UART_CTL_MODE_m (0x7 << RP2_UART_CTL_MODE_s) | ||
144 | #define RP2_UART_CTL_MODE_rs232 (0x1 << RP2_UART_CTL_MODE_s) | ||
145 | #define RP2_UART_CTL_FLUSH_RX_m BIT(3) | ||
146 | #define RP2_UART_CTL_FLUSH_TX_m BIT(4) | ||
147 | #define RP2_UART_CTL_RESET_CH_m BIT(5) | ||
148 | #define RP2_UART_CTL_XMIT_EN_m BIT(6) | ||
149 | #define RP2_UART_CTL_DATABITS_s 8 | ||
150 | #define RP2_UART_CTL_DATABITS_m (0x3 << RP2_UART_CTL_DATABITS_s) | ||
151 | #define RP2_UART_CTL_DATABITS_8 (0x3 << RP2_UART_CTL_DATABITS_s) | ||
152 | #define RP2_UART_CTL_DATABITS_7 (0x2 << RP2_UART_CTL_DATABITS_s) | ||
153 | #define RP2_UART_CTL_DATABITS_6 (0x1 << RP2_UART_CTL_DATABITS_s) | ||
154 | #define RP2_UART_CTL_DATABITS_5 (0x0 << RP2_UART_CTL_DATABITS_s) | ||
155 | #define RP2_UART_CTL_STOPBITS_m BIT(10) | ||
156 | |||
157 | #define RP2_BAUD 0x01c | ||
158 | |||
159 | /* ucode registers */ | ||
160 | #define RP2_TX_SWFLOW 0x02 | ||
161 | #define RP2_TX_SWFLOW_ena 0x81 | ||
162 | #define RP2_TX_SWFLOW_dis 0x9d | ||
163 | |||
164 | #define RP2_RX_SWFLOW 0x0c | ||
165 | #define RP2_RX_SWFLOW_ena 0x81 | ||
166 | #define RP2_RX_SWFLOW_dis 0x8d | ||
167 | |||
168 | #define RP2_RX_FIFO 0x37 | ||
169 | #define RP2_RX_FIFO_ena 0x08 | ||
170 | #define RP2_RX_FIFO_dis 0x81 | ||
171 | |||
172 | static struct uart_driver rp2_uart_driver = { | ||
173 | .owner = THIS_MODULE, | ||
174 | .driver_name = DRV_NAME, | ||
175 | .dev_name = "ttyRP", | ||
176 | .nr = CONFIG_SERIAL_RP2_NR_UARTS, | ||
177 | }; | ||
178 | |||
179 | struct rp2_card; | ||
180 | |||
181 | struct rp2_uart_port { | ||
182 | struct uart_port port; | ||
183 | int idx; | ||
184 | int ignore_rx; | ||
185 | struct rp2_card *card; | ||
186 | void __iomem *asic_base; | ||
187 | void __iomem *base; | ||
188 | void __iomem *ucode; | ||
189 | }; | ||
190 | |||
191 | struct rp2_card { | ||
192 | struct pci_dev *pdev; | ||
193 | struct rp2_uart_port *ports; | ||
194 | int n_ports; | ||
195 | int initialized_ports; | ||
196 | int minor_start; | ||
197 | int smpte; | ||
198 | void __iomem *bar0; | ||
199 | void __iomem *bar1; | ||
200 | spinlock_t card_lock; | ||
201 | struct completion fw_loaded; | ||
202 | }; | ||
203 | |||
204 | #define RP_ID(prod) PCI_VDEVICE(RP, (prod)) | ||
205 | #define RP_CAP(ports, smpte) (((ports) << 8) | ((smpte) << 0)) | ||
206 | |||
207 | static inline void rp2_decode_cap(const struct pci_device_id *id, | ||
208 | int *ports, int *smpte) | ||
209 | { | ||
210 | *ports = id->driver_data >> 8; | ||
211 | *smpte = id->driver_data & 0xff; | ||
212 | } | ||
213 | |||
214 | static DEFINE_SPINLOCK(rp2_minor_lock); | ||
215 | static int rp2_minor_next; | ||
216 | |||
217 | static int rp2_alloc_ports(int n_ports) | ||
218 | { | ||
219 | int ret = -ENOSPC; | ||
220 | |||
221 | spin_lock(&rp2_minor_lock); | ||
222 | if (rp2_minor_next + n_ports <= CONFIG_SERIAL_RP2_NR_UARTS) { | ||
223 | /* sorry, no support for hot unplugging individual cards */ | ||
224 | ret = rp2_minor_next; | ||
225 | rp2_minor_next += n_ports; | ||
226 | } | ||
227 | spin_unlock(&rp2_minor_lock); | ||
228 | |||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | static inline struct rp2_uart_port *port_to_up(struct uart_port *port) | ||
233 | { | ||
234 | return container_of(port, struct rp2_uart_port, port); | ||
235 | } | ||
236 | |||
237 | static void rp2_rmw(struct rp2_uart_port *up, int reg, | ||
238 | u32 clr_bits, u32 set_bits) | ||
239 | { | ||
240 | u32 tmp = readl(up->base + reg); | ||
241 | tmp &= ~clr_bits; | ||
242 | tmp |= set_bits; | ||
243 | writel(tmp, up->base + reg); | ||
244 | } | ||
245 | |||
246 | static void rp2_rmw_clr(struct rp2_uart_port *up, int reg, u32 val) | ||
247 | { | ||
248 | rp2_rmw(up, reg, val, 0); | ||
249 | } | ||
250 | |||
251 | static void rp2_rmw_set(struct rp2_uart_port *up, int reg, u32 val) | ||
252 | { | ||
253 | rp2_rmw(up, reg, 0, val); | ||
254 | } | ||
255 | |||
256 | static void rp2_mask_ch_irq(struct rp2_uart_port *up, int ch_num, | ||
257 | int is_enabled) | ||
258 | { | ||
259 | unsigned long flags, irq_mask; | ||
260 | |||
261 | spin_lock_irqsave(&up->card->card_lock, flags); | ||
262 | |||
263 | irq_mask = readl(up->asic_base + RP2_CH_IRQ_MASK); | ||
264 | if (is_enabled) | ||
265 | irq_mask &= ~BIT(ch_num); | ||
266 | else | ||
267 | irq_mask |= BIT(ch_num); | ||
268 | writel(irq_mask, up->asic_base + RP2_CH_IRQ_MASK); | ||
269 | |||
270 | spin_unlock_irqrestore(&up->card->card_lock, flags); | ||
271 | } | ||
272 | |||
273 | static unsigned int rp2_uart_tx_empty(struct uart_port *port) | ||
274 | { | ||
275 | struct rp2_uart_port *up = port_to_up(port); | ||
276 | unsigned long tx_fifo_bytes, flags; | ||
277 | |||
278 | /* | ||
279 | * This should probably check the transmitter, not the FIFO. | ||
280 | * But the TXEMPTY bit doesn't seem to work unless the TX IRQ is | ||
281 | * enabled. | ||
282 | */ | ||
283 | spin_lock_irqsave(&up->port.lock, flags); | ||
284 | tx_fifo_bytes = readw(up->base + RP2_TX_FIFO_COUNT); | ||
285 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
286 | |||
287 | return tx_fifo_bytes ? 0 : TIOCSER_TEMT; | ||
288 | } | ||
289 | |||
290 | static unsigned int rp2_uart_get_mctrl(struct uart_port *port) | ||
291 | { | ||
292 | struct rp2_uart_port *up = port_to_up(port); | ||
293 | u32 status; | ||
294 | |||
295 | status = readl(up->base + RP2_CHAN_STAT); | ||
296 | return ((status & RP2_CHAN_STAT_DCD_m) ? TIOCM_CAR : 0) | | ||
297 | ((status & RP2_CHAN_STAT_DSR_m) ? TIOCM_DSR : 0) | | ||
298 | ((status & RP2_CHAN_STAT_CTS_m) ? TIOCM_CTS : 0) | | ||
299 | ((status & RP2_CHAN_STAT_RI_m) ? TIOCM_RI : 0); | ||
300 | } | ||
301 | |||
302 | static void rp2_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
303 | { | ||
304 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, | ||
305 | RP2_TXRX_CTL_DTR_m | RP2_TXRX_CTL_RTS_m | RP2_TXRX_CTL_LOOP_m, | ||
306 | ((mctrl & TIOCM_DTR) ? RP2_TXRX_CTL_DTR_m : 0) | | ||
307 | ((mctrl & TIOCM_RTS) ? RP2_TXRX_CTL_RTS_m : 0) | | ||
308 | ((mctrl & TIOCM_LOOP) ? RP2_TXRX_CTL_LOOP_m : 0)); | ||
309 | } | ||
310 | |||
311 | static void rp2_uart_start_tx(struct uart_port *port) | ||
312 | { | ||
313 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); | ||
314 | } | ||
315 | |||
316 | static void rp2_uart_stop_tx(struct uart_port *port) | ||
317 | { | ||
318 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_TXIRQ_m); | ||
319 | } | ||
320 | |||
321 | static void rp2_uart_stop_rx(struct uart_port *port) | ||
322 | { | ||
323 | rp2_rmw_clr(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_RXIRQ_m); | ||
324 | } | ||
325 | |||
326 | static void rp2_uart_break_ctl(struct uart_port *port, int break_state) | ||
327 | { | ||
328 | unsigned long flags; | ||
329 | |||
330 | spin_lock_irqsave(&port->lock, flags); | ||
331 | rp2_rmw(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_BREAK_m, | ||
332 | break_state ? RP2_TXRX_CTL_BREAK_m : 0); | ||
333 | spin_unlock_irqrestore(&port->lock, flags); | ||
334 | } | ||
335 | |||
336 | static void rp2_uart_enable_ms(struct uart_port *port) | ||
337 | { | ||
338 | rp2_rmw_set(port_to_up(port), RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m); | ||
339 | } | ||
340 | |||
341 | static void __rp2_uart_set_termios(struct rp2_uart_port *up, | ||
342 | unsigned long cfl, | ||
343 | unsigned long ifl, | ||
344 | unsigned int baud_div) | ||
345 | { | ||
346 | /* baud rate divisor (calculated elsewhere). 0 = divide-by-1 */ | ||
347 | writew(baud_div - 1, up->base + RP2_BAUD); | ||
348 | |||
349 | /* data bits and stop bits */ | ||
350 | rp2_rmw(up, RP2_UART_CTL, | ||
351 | RP2_UART_CTL_STOPBITS_m | RP2_UART_CTL_DATABITS_m, | ||
352 | ((cfl & CSTOPB) ? RP2_UART_CTL_STOPBITS_m : 0) | | ||
353 | (((cfl & CSIZE) == CS8) ? RP2_UART_CTL_DATABITS_8 : 0) | | ||
354 | (((cfl & CSIZE) == CS7) ? RP2_UART_CTL_DATABITS_7 : 0) | | ||
355 | (((cfl & CSIZE) == CS6) ? RP2_UART_CTL_DATABITS_6 : 0) | | ||
356 | (((cfl & CSIZE) == CS5) ? RP2_UART_CTL_DATABITS_5 : 0)); | ||
357 | |||
358 | /* parity and hardware flow control */ | ||
359 | rp2_rmw(up, RP2_TXRX_CTL, | ||
360 | RP2_TXRX_CTL_PARENB_m | RP2_TXRX_CTL_nPARODD_m | | ||
361 | RP2_TXRX_CTL_CMSPAR_m | RP2_TXRX_CTL_DTRFLOW_m | | ||
362 | RP2_TXRX_CTL_DSRFLOW_m | RP2_TXRX_CTL_RTSFLOW_m | | ||
363 | RP2_TXRX_CTL_CTSFLOW_m, | ||
364 | ((cfl & PARENB) ? RP2_TXRX_CTL_PARENB_m : 0) | | ||
365 | ((cfl & PARODD) ? 0 : RP2_TXRX_CTL_nPARODD_m) | | ||
366 | ((cfl & CMSPAR) ? RP2_TXRX_CTL_CMSPAR_m : 0) | | ||
367 | ((cfl & CRTSCTS) ? (RP2_TXRX_CTL_RTSFLOW_m | | ||
368 | RP2_TXRX_CTL_CTSFLOW_m) : 0)); | ||
369 | |||
370 | /* XON/XOFF software flow control */ | ||
371 | writeb((ifl & IXON) ? RP2_TX_SWFLOW_ena : RP2_TX_SWFLOW_dis, | ||
372 | up->ucode + RP2_TX_SWFLOW); | ||
373 | writeb((ifl & IXOFF) ? RP2_RX_SWFLOW_ena : RP2_RX_SWFLOW_dis, | ||
374 | up->ucode + RP2_RX_SWFLOW); | ||
375 | } | ||
376 | |||
377 | static void rp2_uart_set_termios(struct uart_port *port, | ||
378 | struct ktermios *new, | ||
379 | struct ktermios *old) | ||
380 | { | ||
381 | struct rp2_uart_port *up = port_to_up(port); | ||
382 | unsigned long flags; | ||
383 | unsigned int baud, baud_div; | ||
384 | |||
385 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | ||
386 | baud_div = uart_get_divisor(port, baud); | ||
387 | |||
388 | if (tty_termios_baud_rate(new)) | ||
389 | tty_termios_encode_baud_rate(new, baud, baud); | ||
390 | |||
391 | spin_lock_irqsave(&port->lock, flags); | ||
392 | |||
393 | /* ignore all characters if CREAD is not set */ | ||
394 | port->ignore_status_mask = (new->c_cflag & CREAD) ? 0 : RP2_DUMMY_READ; | ||
395 | |||
396 | __rp2_uart_set_termios(up, new->c_cflag, new->c_iflag, baud_div); | ||
397 | uart_update_timeout(port, new->c_cflag, baud); | ||
398 | |||
399 | spin_unlock_irqrestore(&port->lock, flags); | ||
400 | } | ||
401 | |||
402 | static void rp2_rx_chars(struct rp2_uart_port *up) | ||
403 | { | ||
404 | u16 bytes = readw(up->base + RP2_RX_FIFO_COUNT); | ||
405 | struct tty_port *port = &up->port.state->port; | ||
406 | |||
407 | for (; bytes != 0; bytes--) { | ||
408 | u32 byte = readw(up->base + RP2_DATA_BYTE) | RP2_DUMMY_READ; | ||
409 | char ch = byte & 0xff; | ||
410 | |||
411 | if (likely(!(byte & RP2_DATA_BYTE_EXCEPTION_MASK))) { | ||
412 | if (!uart_handle_sysrq_char(&up->port, ch)) | ||
413 | uart_insert_char(&up->port, byte, 0, ch, | ||
414 | TTY_NORMAL); | ||
415 | } else { | ||
416 | char flag = TTY_NORMAL; | ||
417 | |||
418 | if (byte & RP2_DATA_BYTE_BREAK_m) | ||
419 | flag = TTY_BREAK; | ||
420 | else if (byte & RP2_DATA_BYTE_ERR_FRAMING_m) | ||
421 | flag = TTY_FRAME; | ||
422 | else if (byte & RP2_DATA_BYTE_ERR_PARITY_m) | ||
423 | flag = TTY_PARITY; | ||
424 | uart_insert_char(&up->port, byte, | ||
425 | RP2_DATA_BYTE_ERR_OVERRUN_m, ch, flag); | ||
426 | } | ||
427 | up->port.icount.rx++; | ||
428 | } | ||
429 | |||
430 | tty_flip_buffer_push(port); | ||
431 | } | ||
432 | |||
433 | static void rp2_tx_chars(struct rp2_uart_port *up) | ||
434 | { | ||
435 | u16 max_tx = FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT); | ||
436 | struct circ_buf *xmit = &up->port.state->xmit; | ||
437 | |||
438 | if (uart_tx_stopped(&up->port)) { | ||
439 | rp2_uart_stop_tx(&up->port); | ||
440 | return; | ||
441 | } | ||
442 | |||
443 | for (; max_tx != 0; max_tx--) { | ||
444 | if (up->port.x_char) { | ||
445 | writeb(up->port.x_char, up->base + RP2_DATA_BYTE); | ||
446 | up->port.x_char = 0; | ||
447 | up->port.icount.tx++; | ||
448 | continue; | ||
449 | } | ||
450 | if (uart_circ_empty(xmit)) { | ||
451 | rp2_uart_stop_tx(&up->port); | ||
452 | break; | ||
453 | } | ||
454 | writeb(xmit->buf[xmit->tail], up->base + RP2_DATA_BYTE); | ||
455 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
456 | up->port.icount.tx++; | ||
457 | } | ||
458 | |||
459 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
460 | uart_write_wakeup(&up->port); | ||
461 | } | ||
462 | |||
463 | static void rp2_ch_interrupt(struct rp2_uart_port *up) | ||
464 | { | ||
465 | u32 status; | ||
466 | |||
467 | spin_lock(&up->port.lock); | ||
468 | |||
469 | /* | ||
470 | * The IRQ status bits are clear-on-write. Other status bits in | ||
471 | * this register aren't, so it's harmless to write to them. | ||
472 | */ | ||
473 | status = readl(up->base + RP2_CHAN_STAT); | ||
474 | writel(status, up->base + RP2_CHAN_STAT); | ||
475 | |||
476 | if (status & RP2_CHAN_STAT_RXDATA_m) | ||
477 | rp2_rx_chars(up); | ||
478 | if (status & RP2_CHAN_STAT_TXEMPTY_m) | ||
479 | rp2_tx_chars(up); | ||
480 | if (status & RP2_CHAN_STAT_MS_CHANGED_MASK) | ||
481 | wake_up_interruptible(&up->port.state->port.delta_msr_wait); | ||
482 | |||
483 | spin_unlock(&up->port.lock); | ||
484 | } | ||
485 | |||
486 | static int rp2_asic_interrupt(struct rp2_card *card, unsigned int asic_id) | ||
487 | { | ||
488 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); | ||
489 | int ch, handled = 0; | ||
490 | unsigned long status = readl(base + RP2_CH_IRQ_STAT) & | ||
491 | ~readl(base + RP2_CH_IRQ_MASK); | ||
492 | |||
493 | for_each_set_bit(ch, &status, PORTS_PER_ASIC) { | ||
494 | rp2_ch_interrupt(&card->ports[ch]); | ||
495 | handled++; | ||
496 | } | ||
497 | return handled; | ||
498 | } | ||
499 | |||
500 | static irqreturn_t rp2_uart_interrupt(int irq, void *dev_id) | ||
501 | { | ||
502 | struct rp2_card *card = dev_id; | ||
503 | int handled; | ||
504 | |||
505 | handled = rp2_asic_interrupt(card, 0); | ||
506 | if (card->n_ports >= PORTS_PER_ASIC) | ||
507 | handled += rp2_asic_interrupt(card, 1); | ||
508 | |||
509 | return handled ? IRQ_HANDLED : IRQ_NONE; | ||
510 | } | ||
511 | |||
512 | static inline void rp2_flush_fifos(struct rp2_uart_port *up) | ||
513 | { | ||
514 | rp2_rmw_set(up, RP2_UART_CTL, | ||
515 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); | ||
516 | readl(up->base + RP2_UART_CTL); | ||
517 | udelay(10); | ||
518 | rp2_rmw_clr(up, RP2_UART_CTL, | ||
519 | RP2_UART_CTL_FLUSH_RX_m | RP2_UART_CTL_FLUSH_TX_m); | ||
520 | } | ||
521 | |||
522 | static int rp2_uart_startup(struct uart_port *port) | ||
523 | { | ||
524 | struct rp2_uart_port *up = port_to_up(port); | ||
525 | |||
526 | rp2_flush_fifos(up); | ||
527 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_MSRIRQ_m, RP2_TXRX_CTL_RXIRQ_m); | ||
528 | rp2_rmw(up, RP2_TXRX_CTL, RP2_TXRX_CTL_RX_TRIG_m, | ||
529 | RP2_TXRX_CTL_RX_TRIG_1); | ||
530 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); | ||
531 | rp2_mask_ch_irq(up, up->idx, 1); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static void rp2_uart_shutdown(struct uart_port *port) | ||
537 | { | ||
538 | struct rp2_uart_port *up = port_to_up(port); | ||
539 | unsigned long flags; | ||
540 | |||
541 | rp2_uart_break_ctl(port, 0); | ||
542 | |||
543 | spin_lock_irqsave(&port->lock, flags); | ||
544 | rp2_mask_ch_irq(up, up->idx, 0); | ||
545 | rp2_rmw(up, RP2_CHAN_STAT, 0, 0); | ||
546 | spin_unlock_irqrestore(&port->lock, flags); | ||
547 | } | ||
548 | |||
549 | static const char *rp2_uart_type(struct uart_port *port) | ||
550 | { | ||
551 | return (port->type == PORT_RP2) ? "RocketPort 2 UART" : NULL; | ||
552 | } | ||
553 | |||
554 | static void rp2_uart_release_port(struct uart_port *port) | ||
555 | { | ||
556 | /* Nothing to release ... */ | ||
557 | } | ||
558 | |||
559 | static int rp2_uart_request_port(struct uart_port *port) | ||
560 | { | ||
561 | /* UARTs always present */ | ||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static void rp2_uart_config_port(struct uart_port *port, int flags) | ||
566 | { | ||
567 | if (flags & UART_CONFIG_TYPE) | ||
568 | port->type = PORT_RP2; | ||
569 | } | ||
570 | |||
571 | static int rp2_uart_verify_port(struct uart_port *port, | ||
572 | struct serial_struct *ser) | ||
573 | { | ||
574 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_RP2) | ||
575 | return -EINVAL; | ||
576 | |||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | static const struct uart_ops rp2_uart_ops = { | ||
581 | .tx_empty = rp2_uart_tx_empty, | ||
582 | .set_mctrl = rp2_uart_set_mctrl, | ||
583 | .get_mctrl = rp2_uart_get_mctrl, | ||
584 | .stop_tx = rp2_uart_stop_tx, | ||
585 | .start_tx = rp2_uart_start_tx, | ||
586 | .stop_rx = rp2_uart_stop_rx, | ||
587 | .enable_ms = rp2_uart_enable_ms, | ||
588 | .break_ctl = rp2_uart_break_ctl, | ||
589 | .startup = rp2_uart_startup, | ||
590 | .shutdown = rp2_uart_shutdown, | ||
591 | .set_termios = rp2_uart_set_termios, | ||
592 | .type = rp2_uart_type, | ||
593 | .release_port = rp2_uart_release_port, | ||
594 | .request_port = rp2_uart_request_port, | ||
595 | .config_port = rp2_uart_config_port, | ||
596 | .verify_port = rp2_uart_verify_port, | ||
597 | }; | ||
598 | |||
599 | static void rp2_reset_asic(struct rp2_card *card, unsigned int asic_id) | ||
600 | { | ||
601 | void __iomem *base = card->bar1 + RP2_ASIC_OFFSET(asic_id); | ||
602 | u32 clk_cfg; | ||
603 | |||
604 | writew(1, base + RP2_GLOBAL_CMD); | ||
605 | readw(base + RP2_GLOBAL_CMD); | ||
606 | msleep(100); | ||
607 | writel(0, base + RP2_CLK_PRESCALER); | ||
608 | |||
609 | /* TDM clock configuration */ | ||
610 | clk_cfg = readw(base + RP2_ASIC_CFG); | ||
611 | clk_cfg = (clk_cfg & ~BIT(8)) | BIT(9); | ||
612 | writew(clk_cfg, base + RP2_ASIC_CFG); | ||
613 | |||
614 | /* IRQ routing */ | ||
615 | writel(ALL_PORTS_MASK, base + RP2_CH_IRQ_MASK); | ||
616 | writel(RP2_ASIC_IRQ_EN_m, base + RP2_ASIC_IRQ); | ||
617 | } | ||
618 | |||
619 | static void rp2_init_card(struct rp2_card *card) | ||
620 | { | ||
621 | writel(4, card->bar0 + RP2_FPGA_CTL0); | ||
622 | writel(0, card->bar0 + RP2_FPGA_CTL1); | ||
623 | |||
624 | rp2_reset_asic(card, 0); | ||
625 | if (card->n_ports >= PORTS_PER_ASIC) | ||
626 | rp2_reset_asic(card, 1); | ||
627 | |||
628 | writel(RP2_IRQ_MASK_EN_m, card->bar0 + RP2_IRQ_MASK); | ||
629 | } | ||
630 | |||
631 | static void rp2_init_port(struct rp2_uart_port *up, const struct firmware *fw) | ||
632 | { | ||
633 | int i; | ||
634 | |||
635 | writel(RP2_UART_CTL_RESET_CH_m, up->base + RP2_UART_CTL); | ||
636 | readl(up->base + RP2_UART_CTL); | ||
637 | udelay(1); | ||
638 | |||
639 | writel(0, up->base + RP2_TXRX_CTL); | ||
640 | writel(0, up->base + RP2_UART_CTL); | ||
641 | readl(up->base + RP2_UART_CTL); | ||
642 | udelay(1); | ||
643 | |||
644 | rp2_flush_fifos(up); | ||
645 | |||
646 | for (i = 0; i < min_t(int, fw->size, RP2_UCODE_BYTES); i++) | ||
647 | writeb(fw->data[i], up->ucode + i); | ||
648 | |||
649 | __rp2_uart_set_termios(up, CS8 | CREAD | CLOCAL, 0, DEFAULT_BAUD_DIV); | ||
650 | rp2_uart_set_mctrl(&up->port, 0); | ||
651 | |||
652 | writeb(RP2_RX_FIFO_ena, up->ucode + RP2_RX_FIFO); | ||
653 | rp2_rmw(up, RP2_UART_CTL, RP2_UART_CTL_MODE_m, | ||
654 | RP2_UART_CTL_XMIT_EN_m | RP2_UART_CTL_MODE_rs232); | ||
655 | rp2_rmw_set(up, RP2_TXRX_CTL, | ||
656 | RP2_TXRX_CTL_TX_EN_m | RP2_TXRX_CTL_RX_EN_m); | ||
657 | } | ||
658 | |||
659 | static void rp2_remove_ports(struct rp2_card *card) | ||
660 | { | ||
661 | int i; | ||
662 | |||
663 | for (i = 0; i < card->initialized_ports; i++) | ||
664 | uart_remove_one_port(&rp2_uart_driver, &card->ports[i].port); | ||
665 | card->initialized_ports = 0; | ||
666 | } | ||
667 | |||
668 | static void rp2_fw_cb(const struct firmware *fw, void *context) | ||
669 | { | ||
670 | struct rp2_card *card = context; | ||
671 | resource_size_t phys_base; | ||
672 | int i, rc = -ENOENT; | ||
673 | |||
674 | if (!fw) { | ||
675 | dev_err(&card->pdev->dev, "cannot find '%s' firmware image\n", | ||
676 | RP2_FW_NAME); | ||
677 | goto no_fw; | ||
678 | } | ||
679 | |||
680 | phys_base = pci_resource_start(card->pdev, 1); | ||
681 | |||
682 | for (i = 0; i < card->n_ports; i++) { | ||
683 | struct rp2_uart_port *rp = &card->ports[i]; | ||
684 | struct uart_port *p; | ||
685 | int j = (unsigned)i % PORTS_PER_ASIC; | ||
686 | |||
687 | rp->asic_base = card->bar1; | ||
688 | rp->base = card->bar1 + RP2_PORT_BASE + j*RP2_PORT_SPACING; | ||
689 | rp->ucode = card->bar1 + RP2_UCODE_BASE + j*RP2_UCODE_SPACING; | ||
690 | rp->card = card; | ||
691 | rp->idx = j; | ||
692 | |||
693 | p = &rp->port; | ||
694 | p->line = card->minor_start + i; | ||
695 | p->dev = &card->pdev->dev; | ||
696 | p->type = PORT_RP2; | ||
697 | p->iotype = UPIO_MEM32; | ||
698 | p->uartclk = UART_CLOCK; | ||
699 | p->regshift = 2; | ||
700 | p->fifosize = FIFO_SIZE; | ||
701 | p->ops = &rp2_uart_ops; | ||
702 | p->irq = card->pdev->irq; | ||
703 | p->membase = rp->base; | ||
704 | p->mapbase = phys_base + RP2_PORT_BASE + j*RP2_PORT_SPACING; | ||
705 | |||
706 | if (i >= PORTS_PER_ASIC) { | ||
707 | rp->asic_base += RP2_ASIC_SPACING; | ||
708 | rp->base += RP2_ASIC_SPACING; | ||
709 | rp->ucode += RP2_ASIC_SPACING; | ||
710 | p->mapbase += RP2_ASIC_SPACING; | ||
711 | } | ||
712 | |||
713 | rp2_init_port(rp, fw); | ||
714 | rc = uart_add_one_port(&rp2_uart_driver, p); | ||
715 | if (rc) { | ||
716 | dev_err(&card->pdev->dev, | ||
717 | "error registering port %d: %d\n", i, rc); | ||
718 | rp2_remove_ports(card); | ||
719 | break; | ||
720 | } | ||
721 | card->initialized_ports++; | ||
722 | } | ||
723 | |||
724 | release_firmware(fw); | ||
725 | no_fw: | ||
726 | /* | ||
727 | * rp2_fw_cb() is called from a workqueue long after rp2_probe() | ||
728 | * has already returned success. So if something failed here, | ||
729 | * we'll just leave the now-dormant device in place until somebody | ||
730 | * unbinds it. | ||
731 | */ | ||
732 | if (rc) | ||
733 | dev_warn(&card->pdev->dev, "driver initialization failed\n"); | ||
734 | |||
735 | complete(&card->fw_loaded); | ||
736 | } | ||
737 | |||
738 | static int rp2_probe(struct pci_dev *pdev, | ||
739 | const struct pci_device_id *id) | ||
740 | { | ||
741 | struct rp2_card *card; | ||
742 | struct rp2_uart_port *ports; | ||
743 | void __iomem * const *bars; | ||
744 | int rc; | ||
745 | |||
746 | card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL); | ||
747 | if (!card) | ||
748 | return -ENOMEM; | ||
749 | pci_set_drvdata(pdev, card); | ||
750 | spin_lock_init(&card->card_lock); | ||
751 | init_completion(&card->fw_loaded); | ||
752 | |||
753 | rc = pcim_enable_device(pdev); | ||
754 | if (rc) | ||
755 | return rc; | ||
756 | |||
757 | rc = pcim_iomap_regions_request_all(pdev, 0x03, DRV_NAME); | ||
758 | if (rc) | ||
759 | return rc; | ||
760 | |||
761 | bars = pcim_iomap_table(pdev); | ||
762 | card->bar0 = bars[0]; | ||
763 | card->bar1 = bars[1]; | ||
764 | card->pdev = pdev; | ||
765 | |||
766 | rp2_decode_cap(id, &card->n_ports, &card->smpte); | ||
767 | dev_info(&pdev->dev, "found new card with %d ports\n", card->n_ports); | ||
768 | |||
769 | card->minor_start = rp2_alloc_ports(card->n_ports); | ||
770 | if (card->minor_start < 0) { | ||
771 | dev_err(&pdev->dev, | ||
772 | "too many ports (try increasing CONFIG_SERIAL_RP2_NR_UARTS)\n"); | ||
773 | return -EINVAL; | ||
774 | } | ||
775 | |||
776 | rp2_init_card(card); | ||
777 | |||
778 | ports = devm_kzalloc(&pdev->dev, sizeof(*ports) * card->n_ports, | ||
779 | GFP_KERNEL); | ||
780 | if (!ports) | ||
781 | return -ENOMEM; | ||
782 | card->ports = ports; | ||
783 | |||
784 | rc = devm_request_irq(&pdev->dev, pdev->irq, rp2_uart_interrupt, | ||
785 | IRQF_SHARED, DRV_NAME, card); | ||
786 | if (rc) | ||
787 | return rc; | ||
788 | |||
789 | /* | ||
790 | * Only catastrophic errors (e.g. ENOMEM) are reported here. | ||
791 | * If the FW image is missing, we'll find out in rp2_fw_cb() | ||
792 | * and print an error message. | ||
793 | */ | ||
794 | rc = request_firmware_nowait(THIS_MODULE, 1, RP2_FW_NAME, &pdev->dev, | ||
795 | GFP_KERNEL, card, rp2_fw_cb); | ||
796 | if (rc) | ||
797 | return rc; | ||
798 | dev_dbg(&pdev->dev, "waiting for firmware blob...\n"); | ||
799 | |||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | static void rp2_remove(struct pci_dev *pdev) | ||
804 | { | ||
805 | struct rp2_card *card = pci_get_drvdata(pdev); | ||
806 | |||
807 | wait_for_completion(&card->fw_loaded); | ||
808 | rp2_remove_ports(card); | ||
809 | } | ||
810 | |||
811 | static DEFINE_PCI_DEVICE_TABLE(rp2_pci_tbl) = { | ||
812 | |||
813 | /* RocketPort INFINITY cards */ | ||
814 | |||
815 | { RP_ID(0x0040), RP_CAP(8, 0) }, /* INF Octa, RJ45, selectable */ | ||
816 | { RP_ID(0x0041), RP_CAP(32, 0) }, /* INF 32, ext interface */ | ||
817 | { RP_ID(0x0042), RP_CAP(8, 0) }, /* INF Octa, ext interface */ | ||
818 | { RP_ID(0x0043), RP_CAP(16, 0) }, /* INF 16, ext interface */ | ||
819 | { RP_ID(0x0044), RP_CAP(4, 0) }, /* INF Quad, DB, selectable */ | ||
820 | { RP_ID(0x0045), RP_CAP(8, 0) }, /* INF Octa, DB, selectable */ | ||
821 | { RP_ID(0x0046), RP_CAP(4, 0) }, /* INF Quad, ext interface */ | ||
822 | { RP_ID(0x0047), RP_CAP(4, 0) }, /* INF Quad, RJ45 */ | ||
823 | { RP_ID(0x004a), RP_CAP(4, 0) }, /* INF Plus, Quad */ | ||
824 | { RP_ID(0x004b), RP_CAP(8, 0) }, /* INF Plus, Octa */ | ||
825 | { RP_ID(0x004c), RP_CAP(8, 0) }, /* INF III, Octa */ | ||
826 | { RP_ID(0x004d), RP_CAP(4, 0) }, /* INF III, Quad */ | ||
827 | { RP_ID(0x004e), RP_CAP(2, 0) }, /* INF Plus, 2, RS232 */ | ||
828 | { RP_ID(0x004f), RP_CAP(2, 1) }, /* INF Plus, 2, SMPTE */ | ||
829 | { RP_ID(0x0050), RP_CAP(4, 0) }, /* INF Plus, Quad, RJ45 */ | ||
830 | { RP_ID(0x0051), RP_CAP(8, 0) }, /* INF Plus, Octa, RJ45 */ | ||
831 | { RP_ID(0x0052), RP_CAP(8, 1) }, /* INF Octa, SMPTE */ | ||
832 | |||
833 | /* RocketPort EXPRESS cards */ | ||
834 | |||
835 | { RP_ID(0x0060), RP_CAP(8, 0) }, /* EXP Octa, RJ45, selectable */ | ||
836 | { RP_ID(0x0061), RP_CAP(32, 0) }, /* EXP 32, ext interface */ | ||
837 | { RP_ID(0x0062), RP_CAP(8, 0) }, /* EXP Octa, ext interface */ | ||
838 | { RP_ID(0x0063), RP_CAP(16, 0) }, /* EXP 16, ext interface */ | ||
839 | { RP_ID(0x0064), RP_CAP(4, 0) }, /* EXP Quad, DB, selectable */ | ||
840 | { RP_ID(0x0065), RP_CAP(8, 0) }, /* EXP Octa, DB, selectable */ | ||
841 | { RP_ID(0x0066), RP_CAP(4, 0) }, /* EXP Quad, ext interface */ | ||
842 | { RP_ID(0x0067), RP_CAP(4, 0) }, /* EXP Quad, RJ45 */ | ||
843 | { RP_ID(0x0068), RP_CAP(8, 0) }, /* EXP Octa, RJ11 */ | ||
844 | { RP_ID(0x0072), RP_CAP(8, 1) }, /* EXP Octa, SMPTE */ | ||
845 | { } | ||
846 | }; | ||
847 | MODULE_DEVICE_TABLE(pci, rp2_pci_tbl); | ||
848 | |||
849 | static struct pci_driver rp2_pci_driver = { | ||
850 | .name = DRV_NAME, | ||
851 | .id_table = rp2_pci_tbl, | ||
852 | .probe = rp2_probe, | ||
853 | .remove = rp2_remove, | ||
854 | }; | ||
855 | |||
856 | static int __init rp2_uart_init(void) | ||
857 | { | ||
858 | int rc; | ||
859 | |||
860 | rc = uart_register_driver(&rp2_uart_driver); | ||
861 | if (rc) | ||
862 | return rc; | ||
863 | |||
864 | rc = pci_register_driver(&rp2_pci_driver); | ||
865 | if (rc) { | ||
866 | uart_unregister_driver(&rp2_uart_driver); | ||
867 | return rc; | ||
868 | } | ||
869 | |||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | static void __exit rp2_uart_exit(void) | ||
874 | { | ||
875 | pci_unregister_driver(&rp2_pci_driver); | ||
876 | uart_unregister_driver(&rp2_uart_driver); | ||
877 | } | ||
878 | |||
879 | module_init(rp2_uart_init); | ||
880 | module_exit(rp2_uart_exit); | ||
881 | |||
882 | MODULE_DESCRIPTION("Comtrol RocketPort EXPRESS/INFINITY driver"); | ||
883 | MODULE_AUTHOR("Kevin Cernekee <cernekee@gmail.com>"); | ||
884 | MODULE_LICENSE("GPL v2"); | ||
885 | MODULE_FIRMWARE(RP2_FW_NAME); | ||
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 5d4b9b449b4a..af6b3e3ad24d 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c | |||
@@ -188,7 +188,6 @@ static void sa1100_enable_ms(struct uart_port *port) | |||
188 | static void | 188 | static void |
189 | sa1100_rx_chars(struct sa1100_port *sport) | 189 | sa1100_rx_chars(struct sa1100_port *sport) |
190 | { | 190 | { |
191 | struct tty_struct *tty = sport->port.state->port.tty; | ||
192 | unsigned int status, ch, flg; | 191 | unsigned int status, ch, flg; |
193 | 192 | ||
194 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 193 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
@@ -233,7 +232,7 @@ sa1100_rx_chars(struct sa1100_port *sport) | |||
233 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 232 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
234 | UTSR0_TO_SM(UART_GET_UTSR0(sport)); | 233 | UTSR0_TO_SM(UART_GET_UTSR0(sport)); |
235 | } | 234 | } |
236 | tty_flip_buffer_push(tty); | 235 | tty_flip_buffer_push(&sport->port.state->port); |
237 | } | 236 | } |
238 | 237 | ||
239 | static void sa1100_tx_chars(struct sa1100_port *sport) | 238 | static void sa1100_tx_chars(struct sa1100_port *sport) |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index e514b3a4dc57..2769a38d15b6 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <asm/irq.h> | 47 | #include <asm/irq.h> |
48 | 48 | ||
49 | #include <mach/hardware.h> | 49 | #include <mach/hardware.h> |
50 | #include <mach/map.h> | ||
51 | 50 | ||
52 | #include <plat/regs-serial.h> | 51 | #include <plat/regs-serial.h> |
53 | #include <plat/clock.h> | 52 | #include <plat/clock.h> |
@@ -221,7 +220,6 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
221 | { | 220 | { |
222 | struct s3c24xx_uart_port *ourport = dev_id; | 221 | struct s3c24xx_uart_port *ourport = dev_id; |
223 | struct uart_port *port = &ourport->port; | 222 | struct uart_port *port = &ourport->port; |
224 | struct tty_struct *tty = port->state->port.tty; | ||
225 | unsigned int ufcon, ch, flag, ufstat, uerstat; | 223 | unsigned int ufcon, ch, flag, ufstat, uerstat; |
226 | unsigned long flags; | 224 | unsigned long flags; |
227 | int max_count = 64; | 225 | int max_count = 64; |
@@ -299,7 +297,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
299 | ignore_char: | 297 | ignore_char: |
300 | continue; | 298 | continue; |
301 | } | 299 | } |
302 | tty_flip_buffer_push(tty); | 300 | tty_flip_buffer_push(&port->state->port); |
303 | 301 | ||
304 | out: | 302 | out: |
305 | spin_unlock_irqrestore(&port->lock, flags); | 303 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -1143,8 +1141,13 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1143 | 1141 | ||
1144 | dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); | 1142 | dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); |
1145 | 1143 | ||
1144 | port->membase = devm_ioremap(port->dev, res->start, resource_size(res)); | ||
1145 | if (!port->membase) { | ||
1146 | dev_err(port->dev, "failed to remap controller address\n"); | ||
1147 | return -EBUSY; | ||
1148 | } | ||
1149 | |||
1146 | port->mapbase = res->start; | 1150 | port->mapbase = res->start; |
1147 | port->membase = S3C_VA_UART + (res->start & 0xfffff); | ||
1148 | ret = platform_get_irq(platdev, 0); | 1151 | ret = platform_get_irq(platdev, 0); |
1149 | if (ret < 0) | 1152 | if (ret < 0) |
1150 | port->irq = 0; | 1153 | port->irq = 0; |
@@ -1724,8 +1727,6 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = { | |||
1724 | {}, | 1727 | {}, |
1725 | }; | 1728 | }; |
1726 | MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); | 1729 | MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); |
1727 | #else | ||
1728 | #define s3c24xx_uart_dt_match NULL | ||
1729 | #endif | 1730 | #endif |
1730 | 1731 | ||
1731 | static struct platform_driver samsung_serial_driver = { | 1732 | static struct platform_driver samsung_serial_driver = { |
@@ -1736,7 +1737,7 @@ static struct platform_driver samsung_serial_driver = { | |||
1736 | .name = "samsung-uart", | 1737 | .name = "samsung-uart", |
1737 | .owner = THIS_MODULE, | 1738 | .owner = THIS_MODULE, |
1738 | .pm = SERIAL_SAMSUNG_PM_OPS, | 1739 | .pm = SERIAL_SAMSUNG_PM_OPS, |
1739 | .of_match_table = s3c24xx_uart_dt_match, | 1740 | .of_match_table = of_match_ptr(s3c24xx_uart_dt_match), |
1740 | }, | 1741 | }, |
1741 | }; | 1742 | }; |
1742 | 1743 | ||
diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index f76b1688c5c8..a7cdec2962dd 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c | |||
@@ -384,7 +384,7 @@ static void sbd_receive_chars(struct sbd_port *sport) | |||
384 | uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); | 384 | uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag); |
385 | } | 385 | } |
386 | 386 | ||
387 | tty_flip_buffer_push(uport->state->port.tty); | 387 | tty_flip_buffer_push(&uport->state->port); |
388 | } | 388 | } |
389 | 389 | ||
390 | static void sbd_transmit_chars(struct sbd_port *sport) | 390 | static void sbd_transmit_chars(struct sbd_port *sport) |
diff --git a/drivers/tty/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c index aced1dd923d8..c9735680762d 100644 --- a/drivers/tty/serial/sc26xx.c +++ b/drivers/tty/serial/sc26xx.c | |||
@@ -136,16 +136,17 @@ static void sc26xx_disable_irq(struct uart_port *port, int mask) | |||
136 | WRITE_SC(port, IMR, up->imr); | 136 | WRITE_SC(port, IMR, up->imr); |
137 | } | 137 | } |
138 | 138 | ||
139 | static struct tty_struct *receive_chars(struct uart_port *port) | 139 | static bool receive_chars(struct uart_port *port) |
140 | { | 140 | { |
141 | struct tty_struct *tty = NULL; | 141 | struct tty_port *tport = NULL; |
142 | int limit = 10000; | 142 | int limit = 10000; |
143 | unsigned char ch; | 143 | unsigned char ch; |
144 | char flag; | 144 | char flag; |
145 | u8 status; | 145 | u8 status; |
146 | 146 | ||
147 | /* FIXME what is this trying to achieve? */ | ||
147 | if (port->state != NULL) /* Unopened serial console */ | 148 | if (port->state != NULL) /* Unopened serial console */ |
148 | tty = port->state->port.tty; | 149 | tport = &port->state->port; |
149 | 150 | ||
150 | while (limit-- > 0) { | 151 | while (limit-- > 0) { |
151 | status = READ_SC_PORT(port, SR); | 152 | status = READ_SC_PORT(port, SR); |
@@ -185,9 +186,9 @@ static struct tty_struct *receive_chars(struct uart_port *port) | |||
185 | if (status & port->ignore_status_mask) | 186 | if (status & port->ignore_status_mask) |
186 | continue; | 187 | continue; |
187 | 188 | ||
188 | tty_insert_flip_char(tty, ch, flag); | 189 | tty_insert_flip_char(tport, ch, flag); |
189 | } | 190 | } |
190 | return tty; | 191 | return !!tport; |
191 | } | 192 | } |
192 | 193 | ||
193 | static void transmit_chars(struct uart_port *port) | 194 | static void transmit_chars(struct uart_port *port) |
@@ -217,36 +218,36 @@ static void transmit_chars(struct uart_port *port) | |||
217 | static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) | 218 | static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) |
218 | { | 219 | { |
219 | struct uart_sc26xx_port *up = dev_id; | 220 | struct uart_sc26xx_port *up = dev_id; |
220 | struct tty_struct *tty; | ||
221 | unsigned long flags; | 221 | unsigned long flags; |
222 | bool push; | ||
222 | u8 isr; | 223 | u8 isr; |
223 | 224 | ||
224 | spin_lock_irqsave(&up->port[0].lock, flags); | 225 | spin_lock_irqsave(&up->port[0].lock, flags); |
225 | 226 | ||
226 | tty = NULL; | 227 | push = false; |
227 | isr = READ_SC(&up->port[0], ISR); | 228 | isr = READ_SC(&up->port[0], ISR); |
228 | if (isr & ISR_TXRDYA) | 229 | if (isr & ISR_TXRDYA) |
229 | transmit_chars(&up->port[0]); | 230 | transmit_chars(&up->port[0]); |
230 | if (isr & ISR_RXRDYA) | 231 | if (isr & ISR_RXRDYA) |
231 | tty = receive_chars(&up->port[0]); | 232 | push = receive_chars(&up->port[0]); |
232 | 233 | ||
233 | spin_unlock(&up->port[0].lock); | 234 | spin_unlock(&up->port[0].lock); |
234 | 235 | ||
235 | if (tty) | 236 | if (push) |
236 | tty_flip_buffer_push(tty); | 237 | tty_flip_buffer_push(&up->port[0].state->port); |
237 | 238 | ||
238 | spin_lock(&up->port[1].lock); | 239 | spin_lock(&up->port[1].lock); |
239 | 240 | ||
240 | tty = NULL; | 241 | push = false; |
241 | if (isr & ISR_TXRDYB) | 242 | if (isr & ISR_TXRDYB) |
242 | transmit_chars(&up->port[1]); | 243 | transmit_chars(&up->port[1]); |
243 | if (isr & ISR_RXRDYB) | 244 | if (isr & ISR_RXRDYB) |
244 | tty = receive_chars(&up->port[1]); | 245 | push = receive_chars(&up->port[1]); |
245 | 246 | ||
246 | spin_unlock_irqrestore(&up->port[1].lock, flags); | 247 | spin_unlock_irqrestore(&up->port[1].lock, flags); |
247 | 248 | ||
248 | if (tty) | 249 | if (push) |
249 | tty_flip_buffer_push(tty); | 250 | tty_flip_buffer_push(&up->port[1].state->port); |
250 | 251 | ||
251 | return IRQ_HANDLED; | 252 | return IRQ_HANDLED; |
252 | } | 253 | } |
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index e869eab180be..08dbfb88d42c 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c | |||
@@ -24,8 +24,9 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/tty.h> | 25 | #include <linux/tty.h> |
26 | #include <linux/tty_flip.h> | 26 | #include <linux/tty_flip.h> |
27 | #include <linux/spinlock.h> | ||
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | #include <linux/platform_data/sccnxp.h> | 29 | #include <linux/platform_data/serial-sccnxp.h> |
29 | 30 | ||
30 | #define SCCNXP_NAME "uart-sccnxp" | 31 | #define SCCNXP_NAME "uart-sccnxp" |
31 | #define SCCNXP_MAJOR 204 | 32 | #define SCCNXP_MAJOR 204 |
@@ -107,6 +108,7 @@ enum { | |||
107 | struct sccnxp_port { | 108 | struct sccnxp_port { |
108 | struct uart_driver uart; | 109 | struct uart_driver uart; |
109 | struct uart_port port[SCCNXP_MAX_UARTS]; | 110 | struct uart_port port[SCCNXP_MAX_UARTS]; |
111 | bool opened[SCCNXP_MAX_UARTS]; | ||
110 | 112 | ||
111 | const char *name; | 113 | const char *name; |
112 | int irq; | 114 | int irq; |
@@ -123,7 +125,10 @@ struct sccnxp_port { | |||
123 | struct console console; | 125 | struct console console; |
124 | #endif | 126 | #endif |
125 | 127 | ||
126 | struct mutex sccnxp_mutex; | 128 | spinlock_t lock; |
129 | |||
130 | bool poll; | ||
131 | struct timer_list timer; | ||
127 | 132 | ||
128 | struct sccnxp_pdata pdata; | 133 | struct sccnxp_pdata pdata; |
129 | }; | 134 | }; |
@@ -175,14 +180,12 @@ static int sccnxp_update_best_err(int a, int b, int *besterr) | |||
175 | return 1; | 180 | return 1; |
176 | } | 181 | } |
177 | 182 | ||
178 | struct baud_table { | 183 | static const struct { |
179 | u8 csr; | 184 | u8 csr; |
180 | u8 acr; | 185 | u8 acr; |
181 | u8 mr0; | 186 | u8 mr0; |
182 | int baud; | 187 | int baud; |
183 | }; | 188 | } baud_std[] = { |
184 | |||
185 | const struct baud_table baud_std[] = { | ||
186 | { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, }, | 189 | { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, }, |
187 | { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, }, | 190 | { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, }, |
188 | { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, }, | 191 | { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, }, |
@@ -286,10 +289,6 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
286 | { | 289 | { |
287 | u8 sr; | 290 | u8 sr; |
288 | unsigned int ch, flag; | 291 | unsigned int ch, flag; |
289 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
290 | |||
291 | if (!tty) | ||
292 | return; | ||
293 | 292 | ||
294 | for (;;) { | 293 | for (;;) { |
295 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); | 294 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); |
@@ -305,14 +304,19 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
305 | if (unlikely(sr)) { | 304 | if (unlikely(sr)) { |
306 | if (sr & SR_BRK) { | 305 | if (sr & SR_BRK) { |
307 | port->icount.brk++; | 306 | port->icount.brk++; |
307 | sccnxp_port_write(port, SCCNXP_CR_REG, | ||
308 | CR_CMD_BREAK_RESET); | ||
308 | if (uart_handle_break(port)) | 309 | if (uart_handle_break(port)) |
309 | continue; | 310 | continue; |
310 | } else if (sr & SR_PE) | 311 | } else if (sr & SR_PE) |
311 | port->icount.parity++; | 312 | port->icount.parity++; |
312 | else if (sr & SR_FE) | 313 | else if (sr & SR_FE) |
313 | port->icount.frame++; | 314 | port->icount.frame++; |
314 | else if (sr & SR_OVR) | 315 | else if (sr & SR_OVR) { |
315 | port->icount.overrun++; | 316 | port->icount.overrun++; |
317 | sccnxp_port_write(port, SCCNXP_CR_REG, | ||
318 | CR_CMD_STATUS_RESET); | ||
319 | } | ||
316 | 320 | ||
317 | sr &= port->read_status_mask; | 321 | sr &= port->read_status_mask; |
318 | if (sr & SR_BRK) | 322 | if (sr & SR_BRK) |
@@ -334,9 +338,7 @@ static void sccnxp_handle_rx(struct uart_port *port) | |||
334 | uart_insert_char(port, sr, SR_OVR, ch, flag); | 338 | uart_insert_char(port, sr, SR_OVR, ch, flag); |
335 | } | 339 | } |
336 | 340 | ||
337 | tty_flip_buffer_push(tty); | 341 | tty_flip_buffer_push(&port->state->port); |
338 | |||
339 | tty_kref_put(tty); | ||
340 | } | 342 | } |
341 | 343 | ||
342 | static void sccnxp_handle_tx(struct uart_port *port) | 344 | static void sccnxp_handle_tx(struct uart_port *port) |
@@ -378,31 +380,48 @@ static void sccnxp_handle_tx(struct uart_port *port) | |||
378 | uart_write_wakeup(port); | 380 | uart_write_wakeup(port); |
379 | } | 381 | } |
380 | 382 | ||
381 | static irqreturn_t sccnxp_ist(int irq, void *dev_id) | 383 | static void sccnxp_handle_events(struct sccnxp_port *s) |
382 | { | 384 | { |
383 | int i; | 385 | int i; |
384 | u8 isr; | 386 | u8 isr; |
385 | struct sccnxp_port *s = (struct sccnxp_port *)dev_id; | ||
386 | |||
387 | mutex_lock(&s->sccnxp_mutex); | ||
388 | 387 | ||
389 | for (;;) { | 388 | do { |
390 | isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG); | 389 | isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG); |
391 | isr &= s->imr; | 390 | isr &= s->imr; |
392 | if (!isr) | 391 | if (!isr) |
393 | break; | 392 | break; |
394 | 393 | ||
395 | dev_dbg(s->port[0].dev, "IRQ status: 0x%02x\n", isr); | ||
396 | |||
397 | for (i = 0; i < s->uart.nr; i++) { | 394 | for (i = 0; i < s->uart.nr; i++) { |
398 | if (isr & ISR_RXRDY(i)) | 395 | if (s->opened[i] && (isr & ISR_RXRDY(i))) |
399 | sccnxp_handle_rx(&s->port[i]); | 396 | sccnxp_handle_rx(&s->port[i]); |
400 | if (isr & ISR_TXRDY(i)) | 397 | if (s->opened[i] && (isr & ISR_TXRDY(i))) |
401 | sccnxp_handle_tx(&s->port[i]); | 398 | sccnxp_handle_tx(&s->port[i]); |
402 | } | 399 | } |
403 | } | 400 | } while (1); |
401 | } | ||
402 | |||
403 | static void sccnxp_timer(unsigned long data) | ||
404 | { | ||
405 | struct sccnxp_port *s = (struct sccnxp_port *)data; | ||
406 | unsigned long flags; | ||
404 | 407 | ||
405 | mutex_unlock(&s->sccnxp_mutex); | 408 | spin_lock_irqsave(&s->lock, flags); |
409 | sccnxp_handle_events(s); | ||
410 | spin_unlock_irqrestore(&s->lock, flags); | ||
411 | |||
412 | if (!timer_pending(&s->timer)) | ||
413 | mod_timer(&s->timer, jiffies + | ||
414 | usecs_to_jiffies(s->pdata.poll_time_us)); | ||
415 | } | ||
416 | |||
417 | static irqreturn_t sccnxp_ist(int irq, void *dev_id) | ||
418 | { | ||
419 | struct sccnxp_port *s = (struct sccnxp_port *)dev_id; | ||
420 | unsigned long flags; | ||
421 | |||
422 | spin_lock_irqsave(&s->lock, flags); | ||
423 | sccnxp_handle_events(s); | ||
424 | spin_unlock_irqrestore(&s->lock, flags); | ||
406 | 425 | ||
407 | return IRQ_HANDLED; | 426 | return IRQ_HANDLED; |
408 | } | 427 | } |
@@ -410,8 +429,9 @@ static irqreturn_t sccnxp_ist(int irq, void *dev_id) | |||
410 | static void sccnxp_start_tx(struct uart_port *port) | 429 | static void sccnxp_start_tx(struct uart_port *port) |
411 | { | 430 | { |
412 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 431 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
432 | unsigned long flags; | ||
413 | 433 | ||
414 | mutex_lock(&s->sccnxp_mutex); | 434 | spin_lock_irqsave(&s->lock, flags); |
415 | 435 | ||
416 | /* Set direction to output */ | 436 | /* Set direction to output */ |
417 | if (s->flags & SCCNXP_HAVE_IO) | 437 | if (s->flags & SCCNXP_HAVE_IO) |
@@ -419,7 +439,7 @@ static void sccnxp_start_tx(struct uart_port *port) | |||
419 | 439 | ||
420 | sccnxp_enable_irq(port, IMR_TXRDY); | 440 | sccnxp_enable_irq(port, IMR_TXRDY); |
421 | 441 | ||
422 | mutex_unlock(&s->sccnxp_mutex); | 442 | spin_unlock_irqrestore(&s->lock, flags); |
423 | } | 443 | } |
424 | 444 | ||
425 | static void sccnxp_stop_tx(struct uart_port *port) | 445 | static void sccnxp_stop_tx(struct uart_port *port) |
@@ -430,20 +450,22 @@ static void sccnxp_stop_tx(struct uart_port *port) | |||
430 | static void sccnxp_stop_rx(struct uart_port *port) | 450 | static void sccnxp_stop_rx(struct uart_port *port) |
431 | { | 451 | { |
432 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 452 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
453 | unsigned long flags; | ||
433 | 454 | ||
434 | mutex_lock(&s->sccnxp_mutex); | 455 | spin_lock_irqsave(&s->lock, flags); |
435 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE); | 456 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE); |
436 | mutex_unlock(&s->sccnxp_mutex); | 457 | spin_unlock_irqrestore(&s->lock, flags); |
437 | } | 458 | } |
438 | 459 | ||
439 | static unsigned int sccnxp_tx_empty(struct uart_port *port) | 460 | static unsigned int sccnxp_tx_empty(struct uart_port *port) |
440 | { | 461 | { |
441 | u8 val; | 462 | u8 val; |
463 | unsigned long flags; | ||
442 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 464 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
443 | 465 | ||
444 | mutex_lock(&s->sccnxp_mutex); | 466 | spin_lock_irqsave(&s->lock, flags); |
445 | val = sccnxp_port_read(port, SCCNXP_SR_REG); | 467 | val = sccnxp_port_read(port, SCCNXP_SR_REG); |
446 | mutex_unlock(&s->sccnxp_mutex); | 468 | spin_unlock_irqrestore(&s->lock, flags); |
447 | 469 | ||
448 | return (val & SR_TXEMT) ? TIOCSER_TEMT : 0; | 470 | return (val & SR_TXEMT) ? TIOCSER_TEMT : 0; |
449 | } | 471 | } |
@@ -456,28 +478,30 @@ static void sccnxp_enable_ms(struct uart_port *port) | |||
456 | static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl) | 478 | static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl) |
457 | { | 479 | { |
458 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 480 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
481 | unsigned long flags; | ||
459 | 482 | ||
460 | if (!(s->flags & SCCNXP_HAVE_IO)) | 483 | if (!(s->flags & SCCNXP_HAVE_IO)) |
461 | return; | 484 | return; |
462 | 485 | ||
463 | mutex_lock(&s->sccnxp_mutex); | 486 | spin_lock_irqsave(&s->lock, flags); |
464 | 487 | ||
465 | sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR); | 488 | sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR); |
466 | sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS); | 489 | sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS); |
467 | 490 | ||
468 | mutex_unlock(&s->sccnxp_mutex); | 491 | spin_unlock_irqrestore(&s->lock, flags); |
469 | } | 492 | } |
470 | 493 | ||
471 | static unsigned int sccnxp_get_mctrl(struct uart_port *port) | 494 | static unsigned int sccnxp_get_mctrl(struct uart_port *port) |
472 | { | 495 | { |
473 | u8 bitmask, ipr; | 496 | u8 bitmask, ipr; |
497 | unsigned long flags; | ||
474 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 498 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
475 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | 499 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; |
476 | 500 | ||
477 | if (!(s->flags & SCCNXP_HAVE_IO)) | 501 | if (!(s->flags & SCCNXP_HAVE_IO)) |
478 | return mctrl; | 502 | return mctrl; |
479 | 503 | ||
480 | mutex_lock(&s->sccnxp_mutex); | 504 | spin_lock_irqsave(&s->lock, flags); |
481 | 505 | ||
482 | ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG); | 506 | ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG); |
483 | 507 | ||
@@ -506,7 +530,7 @@ static unsigned int sccnxp_get_mctrl(struct uart_port *port) | |||
506 | mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0; | 530 | mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0; |
507 | } | 531 | } |
508 | 532 | ||
509 | mutex_unlock(&s->sccnxp_mutex); | 533 | spin_unlock_irqrestore(&s->lock, flags); |
510 | 534 | ||
511 | return mctrl; | 535 | return mctrl; |
512 | } | 536 | } |
@@ -514,21 +538,23 @@ static unsigned int sccnxp_get_mctrl(struct uart_port *port) | |||
514 | static void sccnxp_break_ctl(struct uart_port *port, int break_state) | 538 | static void sccnxp_break_ctl(struct uart_port *port, int break_state) |
515 | { | 539 | { |
516 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 540 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
541 | unsigned long flags; | ||
517 | 542 | ||
518 | mutex_lock(&s->sccnxp_mutex); | 543 | spin_lock_irqsave(&s->lock, flags); |
519 | sccnxp_port_write(port, SCCNXP_CR_REG, break_state ? | 544 | sccnxp_port_write(port, SCCNXP_CR_REG, break_state ? |
520 | CR_CMD_START_BREAK : CR_CMD_STOP_BREAK); | 545 | CR_CMD_START_BREAK : CR_CMD_STOP_BREAK); |
521 | mutex_unlock(&s->sccnxp_mutex); | 546 | spin_unlock_irqrestore(&s->lock, flags); |
522 | } | 547 | } |
523 | 548 | ||
524 | static void sccnxp_set_termios(struct uart_port *port, | 549 | static void sccnxp_set_termios(struct uart_port *port, |
525 | struct ktermios *termios, struct ktermios *old) | 550 | struct ktermios *termios, struct ktermios *old) |
526 | { | 551 | { |
527 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 552 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
553 | unsigned long flags; | ||
528 | u8 mr1, mr2; | 554 | u8 mr1, mr2; |
529 | int baud; | 555 | int baud; |
530 | 556 | ||
531 | mutex_lock(&s->sccnxp_mutex); | 557 | spin_lock_irqsave(&s->lock, flags); |
532 | 558 | ||
533 | /* Mask termios capabilities we don't support */ | 559 | /* Mask termios capabilities we don't support */ |
534 | termios->c_cflag &= ~CMSPAR; | 560 | termios->c_cflag &= ~CMSPAR; |
@@ -595,20 +621,22 @@ static void sccnxp_set_termios(struct uart_port *port, | |||
595 | /* Update timeout according to new baud rate */ | 621 | /* Update timeout according to new baud rate */ |
596 | uart_update_timeout(port, termios->c_cflag, baud); | 622 | uart_update_timeout(port, termios->c_cflag, baud); |
597 | 623 | ||
624 | /* Report actual baudrate back to core */ | ||
598 | if (tty_termios_baud_rate(termios)) | 625 | if (tty_termios_baud_rate(termios)) |
599 | tty_termios_encode_baud_rate(termios, baud, baud); | 626 | tty_termios_encode_baud_rate(termios, baud, baud); |
600 | 627 | ||
601 | /* Enable RX & TX */ | 628 | /* Enable RX & TX */ |
602 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); | 629 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); |
603 | 630 | ||
604 | mutex_unlock(&s->sccnxp_mutex); | 631 | spin_unlock_irqrestore(&s->lock, flags); |
605 | } | 632 | } |
606 | 633 | ||
607 | static int sccnxp_startup(struct uart_port *port) | 634 | static int sccnxp_startup(struct uart_port *port) |
608 | { | 635 | { |
609 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 636 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
637 | unsigned long flags; | ||
610 | 638 | ||
611 | mutex_lock(&s->sccnxp_mutex); | 639 | spin_lock_irqsave(&s->lock, flags); |
612 | 640 | ||
613 | if (s->flags & SCCNXP_HAVE_IO) { | 641 | if (s->flags & SCCNXP_HAVE_IO) { |
614 | /* Outputs are controlled manually */ | 642 | /* Outputs are controlled manually */ |
@@ -627,7 +655,9 @@ static int sccnxp_startup(struct uart_port *port) | |||
627 | /* Enable RX interrupt */ | 655 | /* Enable RX interrupt */ |
628 | sccnxp_enable_irq(port, IMR_RXRDY); | 656 | sccnxp_enable_irq(port, IMR_RXRDY); |
629 | 657 | ||
630 | mutex_unlock(&s->sccnxp_mutex); | 658 | s->opened[port->line] = 1; |
659 | |||
660 | spin_unlock_irqrestore(&s->lock, flags); | ||
631 | 661 | ||
632 | return 0; | 662 | return 0; |
633 | } | 663 | } |
@@ -635,8 +665,11 @@ static int sccnxp_startup(struct uart_port *port) | |||
635 | static void sccnxp_shutdown(struct uart_port *port) | 665 | static void sccnxp_shutdown(struct uart_port *port) |
636 | { | 666 | { |
637 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | 667 | struct sccnxp_port *s = dev_get_drvdata(port->dev); |
668 | unsigned long flags; | ||
638 | 669 | ||
639 | mutex_lock(&s->sccnxp_mutex); | 670 | spin_lock_irqsave(&s->lock, flags); |
671 | |||
672 | s->opened[port->line] = 0; | ||
640 | 673 | ||
641 | /* Disable interrupts */ | 674 | /* Disable interrupts */ |
642 | sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY); | 675 | sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY); |
@@ -648,7 +681,7 @@ static void sccnxp_shutdown(struct uart_port *port) | |||
648 | if (s->flags & SCCNXP_HAVE_IO) | 681 | if (s->flags & SCCNXP_HAVE_IO) |
649 | sccnxp_set_bit(port, DIR_OP, 0); | 682 | sccnxp_set_bit(port, DIR_OP, 0); |
650 | 683 | ||
651 | mutex_unlock(&s->sccnxp_mutex); | 684 | spin_unlock_irqrestore(&s->lock, flags); |
652 | } | 685 | } |
653 | 686 | ||
654 | static const char *sccnxp_type(struct uart_port *port) | 687 | static const char *sccnxp_type(struct uart_port *port) |
@@ -722,10 +755,11 @@ static void sccnxp_console_write(struct console *co, const char *c, unsigned n) | |||
722 | { | 755 | { |
723 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; | 756 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; |
724 | struct uart_port *port = &s->port[co->index]; | 757 | struct uart_port *port = &s->port[co->index]; |
758 | unsigned long flags; | ||
725 | 759 | ||
726 | mutex_lock(&s->sccnxp_mutex); | 760 | spin_lock_irqsave(&s->lock, flags); |
727 | uart_console_write(port, c, n, sccnxp_console_putchar); | 761 | uart_console_write(port, c, n, sccnxp_console_putchar); |
728 | mutex_unlock(&s->sccnxp_mutex); | 762 | spin_unlock_irqrestore(&s->lock, flags); |
729 | } | 763 | } |
730 | 764 | ||
731 | static int sccnxp_console_setup(struct console *co, char *options) | 765 | static int sccnxp_console_setup(struct console *co, char *options) |
@@ -764,7 +798,7 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
764 | } | 798 | } |
765 | platform_set_drvdata(pdev, s); | 799 | platform_set_drvdata(pdev, s); |
766 | 800 | ||
767 | mutex_init(&s->sccnxp_mutex); | 801 | spin_lock_init(&s->lock); |
768 | 802 | ||
769 | /* Individual chip settings */ | 803 | /* Individual chip settings */ |
770 | switch (chiptype) { | 804 | switch (chiptype) { |
@@ -861,11 +895,19 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
861 | } else | 895 | } else |
862 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); | 896 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); |
863 | 897 | ||
864 | s->irq = platform_get_irq(pdev, 0); | 898 | if (s->pdata.poll_time_us) { |
865 | if (s->irq <= 0) { | 899 | dev_info(&pdev->dev, "Using poll mode, resolution %u usecs\n", |
866 | dev_err(&pdev->dev, "Missing irq resource data\n"); | 900 | s->pdata.poll_time_us); |
867 | ret = -ENXIO; | 901 | s->poll = 1; |
868 | goto err_out; | 902 | } |
903 | |||
904 | if (!s->poll) { | ||
905 | s->irq = platform_get_irq(pdev, 0); | ||
906 | if (s->irq < 0) { | ||
907 | dev_err(&pdev->dev, "Missing irq resource data\n"); | ||
908 | ret = -ENXIO; | ||
909 | goto err_out; | ||
910 | } | ||
869 | } | 911 | } |
870 | 912 | ||
871 | /* Check input frequency */ | 913 | /* Check input frequency */ |
@@ -929,13 +971,23 @@ static int sccnxp_probe(struct platform_device *pdev) | |||
929 | if (s->pdata.init) | 971 | if (s->pdata.init) |
930 | s->pdata.init(); | 972 | s->pdata.init(); |
931 | 973 | ||
932 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, sccnxp_ist, | 974 | if (!s->poll) { |
933 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 975 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, |
934 | dev_name(&pdev->dev), s); | 976 | sccnxp_ist, |
935 | if (!ret) | 977 | IRQF_TRIGGER_FALLING | |
978 | IRQF_ONESHOT, | ||
979 | dev_name(&pdev->dev), s); | ||
980 | if (!ret) | ||
981 | return 0; | ||
982 | |||
983 | dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq); | ||
984 | } else { | ||
985 | init_timer(&s->timer); | ||
986 | setup_timer(&s->timer, sccnxp_timer, (unsigned long)s); | ||
987 | mod_timer(&s->timer, jiffies + | ||
988 | usecs_to_jiffies(s->pdata.poll_time_us)); | ||
936 | return 0; | 989 | return 0; |
937 | 990 | } | |
938 | dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq); | ||
939 | 991 | ||
940 | err_out: | 992 | err_out: |
941 | platform_set_drvdata(pdev, NULL); | 993 | platform_set_drvdata(pdev, NULL); |
@@ -948,7 +1000,10 @@ static int sccnxp_remove(struct platform_device *pdev) | |||
948 | int i; | 1000 | int i; |
949 | struct sccnxp_port *s = platform_get_drvdata(pdev); | 1001 | struct sccnxp_port *s = platform_get_drvdata(pdev); |
950 | 1002 | ||
951 | devm_free_irq(&pdev->dev, s->irq, s); | 1003 | if (!s->poll) |
1004 | devm_free_irq(&pdev->dev, s->irq, s); | ||
1005 | else | ||
1006 | del_timer_sync(&s->timer); | ||
952 | 1007 | ||
953 | for (i = 0; i < s->uart.nr; i++) | 1008 | for (i = 0; i < s->uart.nr; i++) |
954 | uart_remove_one_port(&s->uart, &s->port[i]); | 1009 | uart_remove_one_port(&s->uart, &s->port[i]); |
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c new file mode 100644 index 000000000000..372de8ade76a --- /dev/null +++ b/drivers/tty/serial/serial-tegra.c | |||
@@ -0,0 +1,1401 @@ | |||
1 | /* | ||
2 | * serial_tegra.c | ||
3 | * | ||
4 | * High-speed serial driver for NVIDIA Tegra SoCs | ||
5 | * | ||
6 | * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved. | ||
7 | * | ||
8 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms and conditions of the GNU General Public License, | ||
12 | * version 2, as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | */ | ||
22 | |||
23 | #include <linux/clk.h> | ||
24 | #include <linux/debugfs.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/dmaengine.h> | ||
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/dmapool.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/irq.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/of.h> | ||
33 | #include <linux/of_device.h> | ||
34 | #include <linux/pagemap.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/serial.h> | ||
37 | #include <linux/serial_8250.h> | ||
38 | #include <linux/serial_core.h> | ||
39 | #include <linux/serial_reg.h> | ||
40 | #include <linux/slab.h> | ||
41 | #include <linux/string.h> | ||
42 | #include <linux/termios.h> | ||
43 | #include <linux/tty.h> | ||
44 | #include <linux/tty_flip.h> | ||
45 | |||
46 | #include <linux/clk/tegra.h> | ||
47 | |||
48 | #define TEGRA_UART_TYPE "TEGRA_UART" | ||
49 | #define TX_EMPTY_STATUS (UART_LSR_TEMT | UART_LSR_THRE) | ||
50 | #define BYTES_TO_ALIGN(x) ((unsigned long)(x) & 0x3) | ||
51 | |||
52 | #define TEGRA_UART_RX_DMA_BUFFER_SIZE 4096 | ||
53 | #define TEGRA_UART_LSR_TXFIFO_FULL 0x100 | ||
54 | #define TEGRA_UART_IER_EORD 0x20 | ||
55 | #define TEGRA_UART_MCR_RTS_EN 0x40 | ||
56 | #define TEGRA_UART_MCR_CTS_EN 0x20 | ||
57 | #define TEGRA_UART_LSR_ANY (UART_LSR_OE | UART_LSR_BI | \ | ||
58 | UART_LSR_PE | UART_LSR_FE) | ||
59 | #define TEGRA_UART_IRDA_CSR 0x08 | ||
60 | #define TEGRA_UART_SIR_ENABLED 0x80 | ||
61 | |||
62 | #define TEGRA_UART_TX_PIO 1 | ||
63 | #define TEGRA_UART_TX_DMA 2 | ||
64 | #define TEGRA_UART_MIN_DMA 16 | ||
65 | #define TEGRA_UART_FIFO_SIZE 32 | ||
66 | |||
67 | /* | ||
68 | * Tx fifo trigger level setting in tegra uart is in | ||
69 | * reverse way then conventional uart. | ||
70 | */ | ||
71 | #define TEGRA_UART_TX_TRIG_16B 0x00 | ||
72 | #define TEGRA_UART_TX_TRIG_8B 0x10 | ||
73 | #define TEGRA_UART_TX_TRIG_4B 0x20 | ||
74 | #define TEGRA_UART_TX_TRIG_1B 0x30 | ||
75 | |||
76 | #define TEGRA_UART_MAXIMUM 5 | ||
77 | |||
78 | /* Default UART setting when started: 115200 no parity, stop, 8 data bits */ | ||
79 | #define TEGRA_UART_DEFAULT_BAUD 115200 | ||
80 | #define TEGRA_UART_DEFAULT_LSR UART_LCR_WLEN8 | ||
81 | |||
82 | /* Tx transfer mode */ | ||
83 | #define TEGRA_TX_PIO 1 | ||
84 | #define TEGRA_TX_DMA 2 | ||
85 | |||
86 | /** | ||
87 | * tegra_uart_chip_data: SOC specific data. | ||
88 | * | ||
89 | * @tx_fifo_full_status: Status flag available for checking tx fifo full. | ||
90 | * @allow_txfifo_reset_fifo_mode: allow_tx fifo reset with fifo mode or not. | ||
91 | * Tegra30 does not allow this. | ||
92 | * @support_clk_src_div: Clock source support the clock divider. | ||
93 | */ | ||
94 | struct tegra_uart_chip_data { | ||
95 | bool tx_fifo_full_status; | ||
96 | bool allow_txfifo_reset_fifo_mode; | ||
97 | bool support_clk_src_div; | ||
98 | }; | ||
99 | |||
100 | struct tegra_uart_port { | ||
101 | struct uart_port uport; | ||
102 | const struct tegra_uart_chip_data *cdata; | ||
103 | |||
104 | struct clk *uart_clk; | ||
105 | unsigned int current_baud; | ||
106 | |||
107 | /* Register shadow */ | ||
108 | unsigned long fcr_shadow; | ||
109 | unsigned long mcr_shadow; | ||
110 | unsigned long lcr_shadow; | ||
111 | unsigned long ier_shadow; | ||
112 | bool rts_active; | ||
113 | |||
114 | int tx_in_progress; | ||
115 | unsigned int tx_bytes; | ||
116 | |||
117 | bool enable_modem_interrupt; | ||
118 | |||
119 | bool rx_timeout; | ||
120 | int rx_in_progress; | ||
121 | int symb_bit; | ||
122 | int dma_req_sel; | ||
123 | |||
124 | struct dma_chan *rx_dma_chan; | ||
125 | struct dma_chan *tx_dma_chan; | ||
126 | dma_addr_t rx_dma_buf_phys; | ||
127 | dma_addr_t tx_dma_buf_phys; | ||
128 | unsigned char *rx_dma_buf_virt; | ||
129 | unsigned char *tx_dma_buf_virt; | ||
130 | struct dma_async_tx_descriptor *tx_dma_desc; | ||
131 | struct dma_async_tx_descriptor *rx_dma_desc; | ||
132 | dma_cookie_t tx_cookie; | ||
133 | dma_cookie_t rx_cookie; | ||
134 | int tx_bytes_requested; | ||
135 | int rx_bytes_requested; | ||
136 | }; | ||
137 | |||
138 | static void tegra_uart_start_next_tx(struct tegra_uart_port *tup); | ||
139 | static int tegra_uart_start_rx_dma(struct tegra_uart_port *tup); | ||
140 | |||
141 | static inline unsigned long tegra_uart_read(struct tegra_uart_port *tup, | ||
142 | unsigned long reg) | ||
143 | { | ||
144 | return readl(tup->uport.membase + (reg << tup->uport.regshift)); | ||
145 | } | ||
146 | |||
147 | static inline void tegra_uart_write(struct tegra_uart_port *tup, unsigned val, | ||
148 | unsigned long reg) | ||
149 | { | ||
150 | writel(val, tup->uport.membase + (reg << tup->uport.regshift)); | ||
151 | } | ||
152 | |||
153 | static inline struct tegra_uart_port *to_tegra_uport(struct uart_port *u) | ||
154 | { | ||
155 | return container_of(u, struct tegra_uart_port, uport); | ||
156 | } | ||
157 | |||
158 | static unsigned int tegra_uart_get_mctrl(struct uart_port *u) | ||
159 | { | ||
160 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
161 | |||
162 | /* | ||
163 | * RI - Ring detector is active | ||
164 | * CD/DCD/CAR - Carrier detect is always active. For some reason | ||
165 | * linux has different names for carrier detect. | ||
166 | * DSR - Data Set ready is active as the hardware doesn't support it. | ||
167 | * Don't know if the linux support this yet? | ||
168 | * CTS - Clear to send. Always set to active, as the hardware handles | ||
169 | * CTS automatically. | ||
170 | */ | ||
171 | if (tup->enable_modem_interrupt) | ||
172 | return TIOCM_RI | TIOCM_CD | TIOCM_DSR | TIOCM_CTS; | ||
173 | return TIOCM_CTS; | ||
174 | } | ||
175 | |||
176 | static void set_rts(struct tegra_uart_port *tup, bool active) | ||
177 | { | ||
178 | unsigned long mcr; | ||
179 | |||
180 | mcr = tup->mcr_shadow; | ||
181 | if (active) | ||
182 | mcr |= TEGRA_UART_MCR_RTS_EN; | ||
183 | else | ||
184 | mcr &= ~TEGRA_UART_MCR_RTS_EN; | ||
185 | if (mcr != tup->mcr_shadow) { | ||
186 | tegra_uart_write(tup, mcr, UART_MCR); | ||
187 | tup->mcr_shadow = mcr; | ||
188 | } | ||
189 | return; | ||
190 | } | ||
191 | |||
192 | static void set_dtr(struct tegra_uart_port *tup, bool active) | ||
193 | { | ||
194 | unsigned long mcr; | ||
195 | |||
196 | mcr = tup->mcr_shadow; | ||
197 | if (active) | ||
198 | mcr |= UART_MCR_DTR; | ||
199 | else | ||
200 | mcr &= ~UART_MCR_DTR; | ||
201 | if (mcr != tup->mcr_shadow) { | ||
202 | tegra_uart_write(tup, mcr, UART_MCR); | ||
203 | tup->mcr_shadow = mcr; | ||
204 | } | ||
205 | return; | ||
206 | } | ||
207 | |||
208 | static void tegra_uart_set_mctrl(struct uart_port *u, unsigned int mctrl) | ||
209 | { | ||
210 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
211 | unsigned long mcr; | ||
212 | int dtr_enable; | ||
213 | |||
214 | mcr = tup->mcr_shadow; | ||
215 | tup->rts_active = !!(mctrl & TIOCM_RTS); | ||
216 | set_rts(tup, tup->rts_active); | ||
217 | |||
218 | dtr_enable = !!(mctrl & TIOCM_DTR); | ||
219 | set_dtr(tup, dtr_enable); | ||
220 | return; | ||
221 | } | ||
222 | |||
223 | static void tegra_uart_break_ctl(struct uart_port *u, int break_ctl) | ||
224 | { | ||
225 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
226 | unsigned long lcr; | ||
227 | |||
228 | lcr = tup->lcr_shadow; | ||
229 | if (break_ctl) | ||
230 | lcr |= UART_LCR_SBC; | ||
231 | else | ||
232 | lcr &= ~UART_LCR_SBC; | ||
233 | tegra_uart_write(tup, lcr, UART_LCR); | ||
234 | tup->lcr_shadow = lcr; | ||
235 | } | ||
236 | |||
237 | /* Wait for a symbol-time. */ | ||
238 | static void tegra_uart_wait_sym_time(struct tegra_uart_port *tup, | ||
239 | unsigned int syms) | ||
240 | { | ||
241 | if (tup->current_baud) | ||
242 | udelay(DIV_ROUND_UP(syms * tup->symb_bit * 1000000, | ||
243 | tup->current_baud)); | ||
244 | } | ||
245 | |||
246 | static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits) | ||
247 | { | ||
248 | unsigned long fcr = tup->fcr_shadow; | ||
249 | |||
250 | if (tup->cdata->allow_txfifo_reset_fifo_mode) { | ||
251 | fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
252 | tegra_uart_write(tup, fcr, UART_FCR); | ||
253 | } else { | ||
254 | fcr &= ~UART_FCR_ENABLE_FIFO; | ||
255 | tegra_uart_write(tup, fcr, UART_FCR); | ||
256 | udelay(60); | ||
257 | fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | ||
258 | tegra_uart_write(tup, fcr, UART_FCR); | ||
259 | fcr |= UART_FCR_ENABLE_FIFO; | ||
260 | tegra_uart_write(tup, fcr, UART_FCR); | ||
261 | } | ||
262 | |||
263 | /* Dummy read to ensure the write is posted */ | ||
264 | tegra_uart_read(tup, UART_SCR); | ||
265 | |||
266 | /* Wait for the flush to propagate. */ | ||
267 | tegra_uart_wait_sym_time(tup, 1); | ||
268 | } | ||
269 | |||
270 | static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) | ||
271 | { | ||
272 | unsigned long rate; | ||
273 | unsigned int divisor; | ||
274 | unsigned long lcr; | ||
275 | int ret; | ||
276 | |||
277 | if (tup->current_baud == baud) | ||
278 | return 0; | ||
279 | |||
280 | if (tup->cdata->support_clk_src_div) { | ||
281 | rate = baud * 16; | ||
282 | ret = clk_set_rate(tup->uart_clk, rate); | ||
283 | if (ret < 0) { | ||
284 | dev_err(tup->uport.dev, | ||
285 | "clk_set_rate() failed for rate %lu\n", rate); | ||
286 | return ret; | ||
287 | } | ||
288 | divisor = 1; | ||
289 | } else { | ||
290 | rate = clk_get_rate(tup->uart_clk); | ||
291 | divisor = DIV_ROUND_CLOSEST(rate, baud * 16); | ||
292 | } | ||
293 | |||
294 | lcr = tup->lcr_shadow; | ||
295 | lcr |= UART_LCR_DLAB; | ||
296 | tegra_uart_write(tup, lcr, UART_LCR); | ||
297 | |||
298 | tegra_uart_write(tup, divisor & 0xFF, UART_TX); | ||
299 | tegra_uart_write(tup, ((divisor >> 8) & 0xFF), UART_IER); | ||
300 | |||
301 | lcr &= ~UART_LCR_DLAB; | ||
302 | tegra_uart_write(tup, lcr, UART_LCR); | ||
303 | |||
304 | /* Dummy read to ensure the write is posted */ | ||
305 | tegra_uart_read(tup, UART_SCR); | ||
306 | |||
307 | tup->current_baud = baud; | ||
308 | |||
309 | /* wait two character intervals at new rate */ | ||
310 | tegra_uart_wait_sym_time(tup, 2); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup, | ||
315 | unsigned long lsr) | ||
316 | { | ||
317 | char flag = TTY_NORMAL; | ||
318 | |||
319 | if (unlikely(lsr & TEGRA_UART_LSR_ANY)) { | ||
320 | if (lsr & UART_LSR_OE) { | ||
321 | /* Overrrun error */ | ||
322 | flag |= TTY_OVERRUN; | ||
323 | tup->uport.icount.overrun++; | ||
324 | dev_err(tup->uport.dev, "Got overrun errors\n"); | ||
325 | } else if (lsr & UART_LSR_PE) { | ||
326 | /* Parity error */ | ||
327 | flag |= TTY_PARITY; | ||
328 | tup->uport.icount.parity++; | ||
329 | dev_err(tup->uport.dev, "Got Parity errors\n"); | ||
330 | } else if (lsr & UART_LSR_FE) { | ||
331 | flag |= TTY_FRAME; | ||
332 | tup->uport.icount.frame++; | ||
333 | dev_err(tup->uport.dev, "Got frame errors\n"); | ||
334 | } else if (lsr & UART_LSR_BI) { | ||
335 | dev_err(tup->uport.dev, "Got Break\n"); | ||
336 | tup->uport.icount.brk++; | ||
337 | /* If FIFO read error without any data, reset Rx FIFO */ | ||
338 | if (!(lsr & UART_LSR_DR) && (lsr & UART_LSR_FIFOE)) | ||
339 | tegra_uart_fifo_reset(tup, UART_FCR_CLEAR_RCVR); | ||
340 | } | ||
341 | } | ||
342 | return flag; | ||
343 | } | ||
344 | |||
345 | static int tegra_uart_request_port(struct uart_port *u) | ||
346 | { | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static void tegra_uart_release_port(struct uart_port *u) | ||
351 | { | ||
352 | /* Nothing to do here */ | ||
353 | } | ||
354 | |||
355 | static void tegra_uart_fill_tx_fifo(struct tegra_uart_port *tup, int max_bytes) | ||
356 | { | ||
357 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
358 | int i; | ||
359 | |||
360 | for (i = 0; i < max_bytes; i++) { | ||
361 | BUG_ON(uart_circ_empty(xmit)); | ||
362 | if (tup->cdata->tx_fifo_full_status) { | ||
363 | unsigned long lsr = tegra_uart_read(tup, UART_LSR); | ||
364 | if ((lsr & TEGRA_UART_LSR_TXFIFO_FULL)) | ||
365 | break; | ||
366 | } | ||
367 | tegra_uart_write(tup, xmit->buf[xmit->tail], UART_TX); | ||
368 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
369 | tup->uport.icount.tx++; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | static void tegra_uart_start_pio_tx(struct tegra_uart_port *tup, | ||
374 | unsigned int bytes) | ||
375 | { | ||
376 | if (bytes > TEGRA_UART_MIN_DMA) | ||
377 | bytes = TEGRA_UART_MIN_DMA; | ||
378 | |||
379 | tup->tx_in_progress = TEGRA_UART_TX_PIO; | ||
380 | tup->tx_bytes = bytes; | ||
381 | tup->ier_shadow |= UART_IER_THRI; | ||
382 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
383 | } | ||
384 | |||
385 | static void tegra_uart_tx_dma_complete(void *args) | ||
386 | { | ||
387 | struct tegra_uart_port *tup = args; | ||
388 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
389 | struct dma_tx_state state; | ||
390 | unsigned long flags; | ||
391 | int count; | ||
392 | |||
393 | dmaengine_tx_status(tup->tx_dma_chan, tup->rx_cookie, &state); | ||
394 | count = tup->tx_bytes_requested - state.residue; | ||
395 | async_tx_ack(tup->tx_dma_desc); | ||
396 | spin_lock_irqsave(&tup->uport.lock, flags); | ||
397 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
398 | tup->tx_in_progress = 0; | ||
399 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
400 | uart_write_wakeup(&tup->uport); | ||
401 | tegra_uart_start_next_tx(tup); | ||
402 | spin_unlock_irqrestore(&tup->uport.lock, flags); | ||
403 | } | ||
404 | |||
405 | static int tegra_uart_start_tx_dma(struct tegra_uart_port *tup, | ||
406 | unsigned long count) | ||
407 | { | ||
408 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
409 | dma_addr_t tx_phys_addr; | ||
410 | |||
411 | dma_sync_single_for_device(tup->uport.dev, tup->tx_dma_buf_phys, | ||
412 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
413 | |||
414 | tup->tx_bytes = count & ~(0xF); | ||
415 | tx_phys_addr = tup->tx_dma_buf_phys + xmit->tail; | ||
416 | tup->tx_dma_desc = dmaengine_prep_slave_single(tup->tx_dma_chan, | ||
417 | tx_phys_addr, tup->tx_bytes, DMA_MEM_TO_DEV, | ||
418 | DMA_PREP_INTERRUPT); | ||
419 | if (!tup->tx_dma_desc) { | ||
420 | dev_err(tup->uport.dev, "Not able to get desc for Tx\n"); | ||
421 | return -EIO; | ||
422 | } | ||
423 | |||
424 | tup->tx_dma_desc->callback = tegra_uart_tx_dma_complete; | ||
425 | tup->tx_dma_desc->callback_param = tup; | ||
426 | tup->tx_in_progress = TEGRA_UART_TX_DMA; | ||
427 | tup->tx_bytes_requested = tup->tx_bytes; | ||
428 | tup->tx_cookie = dmaengine_submit(tup->tx_dma_desc); | ||
429 | dma_async_issue_pending(tup->tx_dma_chan); | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static void tegra_uart_start_next_tx(struct tegra_uart_port *tup) | ||
434 | { | ||
435 | unsigned long tail; | ||
436 | unsigned long count; | ||
437 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
438 | |||
439 | tail = (unsigned long)&xmit->buf[xmit->tail]; | ||
440 | count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); | ||
441 | if (!count) | ||
442 | return; | ||
443 | |||
444 | if (count < TEGRA_UART_MIN_DMA) | ||
445 | tegra_uart_start_pio_tx(tup, count); | ||
446 | else if (BYTES_TO_ALIGN(tail) > 0) | ||
447 | tegra_uart_start_pio_tx(tup, BYTES_TO_ALIGN(tail)); | ||
448 | else | ||
449 | tegra_uart_start_tx_dma(tup, count); | ||
450 | } | ||
451 | |||
452 | /* Called by serial core driver with u->lock taken. */ | ||
453 | static void tegra_uart_start_tx(struct uart_port *u) | ||
454 | { | ||
455 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
456 | struct circ_buf *xmit = &u->state->xmit; | ||
457 | |||
458 | if (!uart_circ_empty(xmit) && !tup->tx_in_progress) | ||
459 | tegra_uart_start_next_tx(tup); | ||
460 | } | ||
461 | |||
462 | static unsigned int tegra_uart_tx_empty(struct uart_port *u) | ||
463 | { | ||
464 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
465 | unsigned int ret = 0; | ||
466 | unsigned long flags; | ||
467 | |||
468 | spin_lock_irqsave(&u->lock, flags); | ||
469 | if (!tup->tx_in_progress) { | ||
470 | unsigned long lsr = tegra_uart_read(tup, UART_LSR); | ||
471 | if ((lsr & TX_EMPTY_STATUS) == TX_EMPTY_STATUS) | ||
472 | ret = TIOCSER_TEMT; | ||
473 | } | ||
474 | spin_unlock_irqrestore(&u->lock, flags); | ||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | static void tegra_uart_stop_tx(struct uart_port *u) | ||
479 | { | ||
480 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
481 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
482 | struct dma_tx_state state; | ||
483 | int count; | ||
484 | |||
485 | dmaengine_terminate_all(tup->tx_dma_chan); | ||
486 | dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); | ||
487 | count = tup->tx_bytes_requested - state.residue; | ||
488 | async_tx_ack(tup->tx_dma_desc); | ||
489 | xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); | ||
490 | tup->tx_in_progress = 0; | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | static void tegra_uart_handle_tx_pio(struct tegra_uart_port *tup) | ||
495 | { | ||
496 | struct circ_buf *xmit = &tup->uport.state->xmit; | ||
497 | |||
498 | tegra_uart_fill_tx_fifo(tup, tup->tx_bytes); | ||
499 | tup->tx_in_progress = 0; | ||
500 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
501 | uart_write_wakeup(&tup->uport); | ||
502 | tegra_uart_start_next_tx(tup); | ||
503 | return; | ||
504 | } | ||
505 | |||
506 | static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, | ||
507 | struct tty_port *tty) | ||
508 | { | ||
509 | do { | ||
510 | char flag = TTY_NORMAL; | ||
511 | unsigned long lsr = 0; | ||
512 | unsigned char ch; | ||
513 | |||
514 | lsr = tegra_uart_read(tup, UART_LSR); | ||
515 | if (!(lsr & UART_LSR_DR)) | ||
516 | break; | ||
517 | |||
518 | flag = tegra_uart_decode_rx_error(tup, lsr); | ||
519 | ch = (unsigned char) tegra_uart_read(tup, UART_RX); | ||
520 | tup->uport.icount.rx++; | ||
521 | |||
522 | if (!uart_handle_sysrq_char(&tup->uport, ch) && tty) | ||
523 | tty_insert_flip_char(tty, ch, flag); | ||
524 | } while (1); | ||
525 | |||
526 | return; | ||
527 | } | ||
528 | |||
529 | static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup, | ||
530 | struct tty_port *tty, int count) | ||
531 | { | ||
532 | int copied; | ||
533 | |||
534 | tup->uport.icount.rx += count; | ||
535 | if (!tty) { | ||
536 | dev_err(tup->uport.dev, "No tty port\n"); | ||
537 | return; | ||
538 | } | ||
539 | dma_sync_single_for_cpu(tup->uport.dev, tup->rx_dma_buf_phys, | ||
540 | TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_FROM_DEVICE); | ||
541 | copied = tty_insert_flip_string(tty, | ||
542 | ((unsigned char *)(tup->rx_dma_buf_virt)), count); | ||
543 | if (copied != count) { | ||
544 | WARN_ON(1); | ||
545 | dev_err(tup->uport.dev, "RxData copy to tty layer failed\n"); | ||
546 | } | ||
547 | dma_sync_single_for_device(tup->uport.dev, tup->rx_dma_buf_phys, | ||
548 | TEGRA_UART_RX_DMA_BUFFER_SIZE, DMA_TO_DEVICE); | ||
549 | } | ||
550 | |||
551 | static void tegra_uart_rx_dma_complete(void *args) | ||
552 | { | ||
553 | struct tegra_uart_port *tup = args; | ||
554 | struct uart_port *u = &tup->uport; | ||
555 | int count = tup->rx_bytes_requested; | ||
556 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
557 | struct tty_port *port = &u->state->port; | ||
558 | unsigned long flags; | ||
559 | |||
560 | async_tx_ack(tup->rx_dma_desc); | ||
561 | spin_lock_irqsave(&u->lock, flags); | ||
562 | |||
563 | /* Deactivate flow control to stop sender */ | ||
564 | if (tup->rts_active) | ||
565 | set_rts(tup, false); | ||
566 | |||
567 | /* If we are here, DMA is stopped */ | ||
568 | if (count) | ||
569 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
570 | |||
571 | tegra_uart_handle_rx_pio(tup, port); | ||
572 | if (tty) { | ||
573 | tty_flip_buffer_push(port); | ||
574 | tty_kref_put(tty); | ||
575 | } | ||
576 | tegra_uart_start_rx_dma(tup); | ||
577 | |||
578 | /* Activate flow control to start transfer */ | ||
579 | if (tup->rts_active) | ||
580 | set_rts(tup, true); | ||
581 | |||
582 | spin_unlock_irqrestore(&u->lock, flags); | ||
583 | } | ||
584 | |||
585 | static void tegra_uart_handle_rx_dma(struct tegra_uart_port *tup) | ||
586 | { | ||
587 | struct dma_tx_state state; | ||
588 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
589 | struct tty_port *port = &tup->uport.state->port; | ||
590 | int count; | ||
591 | |||
592 | /* Deactivate flow control to stop sender */ | ||
593 | if (tup->rts_active) | ||
594 | set_rts(tup, false); | ||
595 | |||
596 | dmaengine_terminate_all(tup->rx_dma_chan); | ||
597 | dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); | ||
598 | count = tup->rx_bytes_requested - state.residue; | ||
599 | |||
600 | /* If we are here, DMA is stopped */ | ||
601 | if (count) | ||
602 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
603 | |||
604 | tegra_uart_handle_rx_pio(tup, port); | ||
605 | if (tty) { | ||
606 | tty_flip_buffer_push(port); | ||
607 | tty_kref_put(tty); | ||
608 | } | ||
609 | tegra_uart_start_rx_dma(tup); | ||
610 | |||
611 | if (tup->rts_active) | ||
612 | set_rts(tup, true); | ||
613 | } | ||
614 | |||
615 | static int tegra_uart_start_rx_dma(struct tegra_uart_port *tup) | ||
616 | { | ||
617 | unsigned int count = TEGRA_UART_RX_DMA_BUFFER_SIZE; | ||
618 | |||
619 | tup->rx_dma_desc = dmaengine_prep_slave_single(tup->rx_dma_chan, | ||
620 | tup->rx_dma_buf_phys, count, DMA_DEV_TO_MEM, | ||
621 | DMA_PREP_INTERRUPT); | ||
622 | if (!tup->rx_dma_desc) { | ||
623 | dev_err(tup->uport.dev, "Not able to get desc for Rx\n"); | ||
624 | return -EIO; | ||
625 | } | ||
626 | |||
627 | tup->rx_dma_desc->callback = tegra_uart_rx_dma_complete; | ||
628 | tup->rx_dma_desc->callback_param = tup; | ||
629 | dma_sync_single_for_device(tup->uport.dev, tup->rx_dma_buf_phys, | ||
630 | count, DMA_TO_DEVICE); | ||
631 | tup->rx_bytes_requested = count; | ||
632 | tup->rx_cookie = dmaengine_submit(tup->rx_dma_desc); | ||
633 | dma_async_issue_pending(tup->rx_dma_chan); | ||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static void tegra_uart_handle_modem_signal_change(struct uart_port *u) | ||
638 | { | ||
639 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
640 | unsigned long msr; | ||
641 | |||
642 | msr = tegra_uart_read(tup, UART_MSR); | ||
643 | if (!(msr & UART_MSR_ANY_DELTA)) | ||
644 | return; | ||
645 | |||
646 | if (msr & UART_MSR_TERI) | ||
647 | tup->uport.icount.rng++; | ||
648 | if (msr & UART_MSR_DDSR) | ||
649 | tup->uport.icount.dsr++; | ||
650 | /* We may only get DDCD when HW init and reset */ | ||
651 | if (msr & UART_MSR_DDCD) | ||
652 | uart_handle_dcd_change(&tup->uport, msr & UART_MSR_DCD); | ||
653 | /* Will start/stop_tx accordingly */ | ||
654 | if (msr & UART_MSR_DCTS) | ||
655 | uart_handle_cts_change(&tup->uport, msr & UART_MSR_CTS); | ||
656 | return; | ||
657 | } | ||
658 | |||
659 | static irqreturn_t tegra_uart_isr(int irq, void *data) | ||
660 | { | ||
661 | struct tegra_uart_port *tup = data; | ||
662 | struct uart_port *u = &tup->uport; | ||
663 | unsigned long iir; | ||
664 | unsigned long ier; | ||
665 | bool is_rx_int = false; | ||
666 | unsigned long flags; | ||
667 | |||
668 | spin_lock_irqsave(&u->lock, flags); | ||
669 | while (1) { | ||
670 | iir = tegra_uart_read(tup, UART_IIR); | ||
671 | if (iir & UART_IIR_NO_INT) { | ||
672 | if (is_rx_int) { | ||
673 | tegra_uart_handle_rx_dma(tup); | ||
674 | if (tup->rx_in_progress) { | ||
675 | ier = tup->ier_shadow; | ||
676 | ier |= (UART_IER_RLSI | UART_IER_RTOIE | | ||
677 | TEGRA_UART_IER_EORD); | ||
678 | tup->ier_shadow = ier; | ||
679 | tegra_uart_write(tup, ier, UART_IER); | ||
680 | } | ||
681 | } | ||
682 | spin_unlock_irqrestore(&u->lock, flags); | ||
683 | return IRQ_HANDLED; | ||
684 | } | ||
685 | |||
686 | switch ((iir >> 1) & 0x7) { | ||
687 | case 0: /* Modem signal change interrupt */ | ||
688 | tegra_uart_handle_modem_signal_change(u); | ||
689 | break; | ||
690 | |||
691 | case 1: /* Transmit interrupt only triggered when using PIO */ | ||
692 | tup->ier_shadow &= ~UART_IER_THRI; | ||
693 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
694 | tegra_uart_handle_tx_pio(tup); | ||
695 | break; | ||
696 | |||
697 | case 4: /* End of data */ | ||
698 | case 6: /* Rx timeout */ | ||
699 | case 2: /* Receive */ | ||
700 | if (!is_rx_int) { | ||
701 | is_rx_int = true; | ||
702 | /* Disable Rx interrupts */ | ||
703 | ier = tup->ier_shadow; | ||
704 | ier |= UART_IER_RDI; | ||
705 | tegra_uart_write(tup, ier, UART_IER); | ||
706 | ier &= ~(UART_IER_RDI | UART_IER_RLSI | | ||
707 | UART_IER_RTOIE | TEGRA_UART_IER_EORD); | ||
708 | tup->ier_shadow = ier; | ||
709 | tegra_uart_write(tup, ier, UART_IER); | ||
710 | } | ||
711 | break; | ||
712 | |||
713 | case 3: /* Receive error */ | ||
714 | tegra_uart_decode_rx_error(tup, | ||
715 | tegra_uart_read(tup, UART_LSR)); | ||
716 | break; | ||
717 | |||
718 | case 5: /* break nothing to handle */ | ||
719 | case 7: /* break nothing to handle */ | ||
720 | break; | ||
721 | } | ||
722 | } | ||
723 | } | ||
724 | |||
725 | static void tegra_uart_stop_rx(struct uart_port *u) | ||
726 | { | ||
727 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
728 | struct tty_struct *tty = tty_port_tty_get(&tup->uport.state->port); | ||
729 | struct tty_port *port = &u->state->port; | ||
730 | struct dma_tx_state state; | ||
731 | unsigned long ier; | ||
732 | int count; | ||
733 | |||
734 | if (tup->rts_active) | ||
735 | set_rts(tup, false); | ||
736 | |||
737 | if (!tup->rx_in_progress) | ||
738 | return; | ||
739 | |||
740 | tegra_uart_wait_sym_time(tup, 1); /* wait a character interval */ | ||
741 | |||
742 | ier = tup->ier_shadow; | ||
743 | ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | | ||
744 | TEGRA_UART_IER_EORD); | ||
745 | tup->ier_shadow = ier; | ||
746 | tegra_uart_write(tup, ier, UART_IER); | ||
747 | tup->rx_in_progress = 0; | ||
748 | if (tup->rx_dma_chan) { | ||
749 | dmaengine_terminate_all(tup->rx_dma_chan); | ||
750 | dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state); | ||
751 | async_tx_ack(tup->rx_dma_desc); | ||
752 | count = tup->rx_bytes_requested - state.residue; | ||
753 | tegra_uart_copy_rx_to_tty(tup, port, count); | ||
754 | tegra_uart_handle_rx_pio(tup, port); | ||
755 | } else { | ||
756 | tegra_uart_handle_rx_pio(tup, port); | ||
757 | } | ||
758 | if (tty) { | ||
759 | tty_flip_buffer_push(port); | ||
760 | tty_kref_put(tty); | ||
761 | } | ||
762 | return; | ||
763 | } | ||
764 | |||
765 | static void tegra_uart_hw_deinit(struct tegra_uart_port *tup) | ||
766 | { | ||
767 | unsigned long flags; | ||
768 | unsigned long char_time = DIV_ROUND_UP(10000000, tup->current_baud); | ||
769 | unsigned long fifo_empty_time = tup->uport.fifosize * char_time; | ||
770 | unsigned long wait_time; | ||
771 | unsigned long lsr; | ||
772 | unsigned long msr; | ||
773 | unsigned long mcr; | ||
774 | |||
775 | /* Disable interrupts */ | ||
776 | tegra_uart_write(tup, 0, UART_IER); | ||
777 | |||
778 | lsr = tegra_uart_read(tup, UART_LSR); | ||
779 | if ((lsr & UART_LSR_TEMT) != UART_LSR_TEMT) { | ||
780 | msr = tegra_uart_read(tup, UART_MSR); | ||
781 | mcr = tegra_uart_read(tup, UART_MCR); | ||
782 | if ((mcr & TEGRA_UART_MCR_CTS_EN) && (msr & UART_MSR_CTS)) | ||
783 | dev_err(tup->uport.dev, | ||
784 | "Tx Fifo not empty, CTS disabled, waiting\n"); | ||
785 | |||
786 | /* Wait for Tx fifo to be empty */ | ||
787 | while ((lsr & UART_LSR_TEMT) != UART_LSR_TEMT) { | ||
788 | wait_time = min(fifo_empty_time, 100lu); | ||
789 | udelay(wait_time); | ||
790 | fifo_empty_time -= wait_time; | ||
791 | if (!fifo_empty_time) { | ||
792 | msr = tegra_uart_read(tup, UART_MSR); | ||
793 | mcr = tegra_uart_read(tup, UART_MCR); | ||
794 | if ((mcr & TEGRA_UART_MCR_CTS_EN) && | ||
795 | (msr & UART_MSR_CTS)) | ||
796 | dev_err(tup->uport.dev, | ||
797 | "Slave not ready\n"); | ||
798 | break; | ||
799 | } | ||
800 | lsr = tegra_uart_read(tup, UART_LSR); | ||
801 | } | ||
802 | } | ||
803 | |||
804 | spin_lock_irqsave(&tup->uport.lock, flags); | ||
805 | /* Reset the Rx and Tx FIFOs */ | ||
806 | tegra_uart_fifo_reset(tup, UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR); | ||
807 | tup->current_baud = 0; | ||
808 | spin_unlock_irqrestore(&tup->uport.lock, flags); | ||
809 | |||
810 | clk_disable_unprepare(tup->uart_clk); | ||
811 | } | ||
812 | |||
813 | static int tegra_uart_hw_init(struct tegra_uart_port *tup) | ||
814 | { | ||
815 | int ret; | ||
816 | |||
817 | tup->fcr_shadow = 0; | ||
818 | tup->mcr_shadow = 0; | ||
819 | tup->lcr_shadow = 0; | ||
820 | tup->ier_shadow = 0; | ||
821 | tup->current_baud = 0; | ||
822 | |||
823 | clk_prepare_enable(tup->uart_clk); | ||
824 | |||
825 | /* Reset the UART controller to clear all previous status.*/ | ||
826 | tegra_periph_reset_assert(tup->uart_clk); | ||
827 | udelay(10); | ||
828 | tegra_periph_reset_deassert(tup->uart_clk); | ||
829 | |||
830 | tup->rx_in_progress = 0; | ||
831 | tup->tx_in_progress = 0; | ||
832 | |||
833 | /* | ||
834 | * Set the trigger level | ||
835 | * | ||
836 | * For PIO mode: | ||
837 | * | ||
838 | * For receive, this will interrupt the CPU after that many number of | ||
839 | * bytes are received, for the remaining bytes the receive timeout | ||
840 | * interrupt is received. Rx high watermark is set to 4. | ||
841 | * | ||
842 | * For transmit, if the trasnmit interrupt is enabled, this will | ||
843 | * interrupt the CPU when the number of entries in the FIFO reaches the | ||
844 | * low watermark. Tx low watermark is set to 16 bytes. | ||
845 | * | ||
846 | * For DMA mode: | ||
847 | * | ||
848 | * Set the Tx trigger to 16. This should match the DMA burst size that | ||
849 | * programmed in the DMA registers. | ||
850 | */ | ||
851 | tup->fcr_shadow = UART_FCR_ENABLE_FIFO; | ||
852 | tup->fcr_shadow |= UART_FCR_R_TRIG_01; | ||
853 | tup->fcr_shadow |= TEGRA_UART_TX_TRIG_16B; | ||
854 | tegra_uart_write(tup, tup->fcr_shadow, UART_FCR); | ||
855 | |||
856 | /* | ||
857 | * Initialize the UART with default configuration | ||
858 | * (115200, N, 8, 1) so that the receive DMA buffer may be | ||
859 | * enqueued | ||
860 | */ | ||
861 | tup->lcr_shadow = TEGRA_UART_DEFAULT_LSR; | ||
862 | tegra_set_baudrate(tup, TEGRA_UART_DEFAULT_BAUD); | ||
863 | tup->fcr_shadow |= UART_FCR_DMA_SELECT; | ||
864 | tegra_uart_write(tup, tup->fcr_shadow, UART_FCR); | ||
865 | |||
866 | ret = tegra_uart_start_rx_dma(tup); | ||
867 | if (ret < 0) { | ||
868 | dev_err(tup->uport.dev, "Not able to start Rx DMA\n"); | ||
869 | return ret; | ||
870 | } | ||
871 | tup->rx_in_progress = 1; | ||
872 | |||
873 | /* | ||
874 | * Enable IE_RXS for the receive status interrupts like line errros. | ||
875 | * Enable IE_RX_TIMEOUT to get the bytes which cannot be DMA'd. | ||
876 | * | ||
877 | * If using DMA mode, enable EORD instead of receive interrupt which | ||
878 | * will interrupt after the UART is done with the receive instead of | ||
879 | * the interrupt when the FIFO "threshold" is reached. | ||
880 | * | ||
881 | * EORD is different interrupt than RX_TIMEOUT - RX_TIMEOUT occurs when | ||
882 | * the DATA is sitting in the FIFO and couldn't be transferred to the | ||
883 | * DMA as the DMA size alignment(4 bytes) is not met. EORD will be | ||
884 | * triggered when there is a pause of the incomming data stream for 4 | ||
885 | * characters long. | ||
886 | * | ||
887 | * For pauses in the data which is not aligned to 4 bytes, we get | ||
888 | * both the EORD as well as RX_TIMEOUT - SW sees RX_TIMEOUT first | ||
889 | * then the EORD. | ||
890 | */ | ||
891 | tup->ier_shadow = UART_IER_RLSI | UART_IER_RTOIE | TEGRA_UART_IER_EORD; | ||
892 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | static int tegra_uart_dma_channel_allocate(struct tegra_uart_port *tup, | ||
897 | bool dma_to_memory) | ||
898 | { | ||
899 | struct dma_chan *dma_chan; | ||
900 | unsigned char *dma_buf; | ||
901 | dma_addr_t dma_phys; | ||
902 | int ret; | ||
903 | struct dma_slave_config dma_sconfig; | ||
904 | dma_cap_mask_t mask; | ||
905 | |||
906 | dma_cap_zero(mask); | ||
907 | dma_cap_set(DMA_SLAVE, mask); | ||
908 | dma_chan = dma_request_channel(mask, NULL, NULL); | ||
909 | if (!dma_chan) { | ||
910 | dev_err(tup->uport.dev, | ||
911 | "Dma channel is not available, will try later\n"); | ||
912 | return -EPROBE_DEFER; | ||
913 | } | ||
914 | |||
915 | if (dma_to_memory) { | ||
916 | dma_buf = dma_alloc_coherent(tup->uport.dev, | ||
917 | TEGRA_UART_RX_DMA_BUFFER_SIZE, | ||
918 | &dma_phys, GFP_KERNEL); | ||
919 | if (!dma_buf) { | ||
920 | dev_err(tup->uport.dev, | ||
921 | "Not able to allocate the dma buffer\n"); | ||
922 | dma_release_channel(dma_chan); | ||
923 | return -ENOMEM; | ||
924 | } | ||
925 | } else { | ||
926 | dma_phys = dma_map_single(tup->uport.dev, | ||
927 | tup->uport.state->xmit.buf, UART_XMIT_SIZE, | ||
928 | DMA_TO_DEVICE); | ||
929 | dma_buf = tup->uport.state->xmit.buf; | ||
930 | } | ||
931 | |||
932 | dma_sconfig.slave_id = tup->dma_req_sel; | ||
933 | if (dma_to_memory) { | ||
934 | dma_sconfig.src_addr = tup->uport.mapbase; | ||
935 | dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
936 | dma_sconfig.src_maxburst = 4; | ||
937 | } else { | ||
938 | dma_sconfig.dst_addr = tup->uport.mapbase; | ||
939 | dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
940 | dma_sconfig.dst_maxburst = 16; | ||
941 | } | ||
942 | |||
943 | ret = dmaengine_slave_config(dma_chan, &dma_sconfig); | ||
944 | if (ret < 0) { | ||
945 | dev_err(tup->uport.dev, | ||
946 | "Dma slave config failed, err = %d\n", ret); | ||
947 | goto scrub; | ||
948 | } | ||
949 | |||
950 | if (dma_to_memory) { | ||
951 | tup->rx_dma_chan = dma_chan; | ||
952 | tup->rx_dma_buf_virt = dma_buf; | ||
953 | tup->rx_dma_buf_phys = dma_phys; | ||
954 | } else { | ||
955 | tup->tx_dma_chan = dma_chan; | ||
956 | tup->tx_dma_buf_virt = dma_buf; | ||
957 | tup->tx_dma_buf_phys = dma_phys; | ||
958 | } | ||
959 | return 0; | ||
960 | |||
961 | scrub: | ||
962 | dma_release_channel(dma_chan); | ||
963 | return ret; | ||
964 | } | ||
965 | |||
966 | static void tegra_uart_dma_channel_free(struct tegra_uart_port *tup, | ||
967 | bool dma_to_memory) | ||
968 | { | ||
969 | struct dma_chan *dma_chan; | ||
970 | |||
971 | if (dma_to_memory) { | ||
972 | dma_free_coherent(tup->uport.dev, TEGRA_UART_RX_DMA_BUFFER_SIZE, | ||
973 | tup->rx_dma_buf_virt, tup->rx_dma_buf_phys); | ||
974 | dma_chan = tup->rx_dma_chan; | ||
975 | tup->rx_dma_chan = NULL; | ||
976 | tup->rx_dma_buf_phys = 0; | ||
977 | tup->rx_dma_buf_virt = NULL; | ||
978 | } else { | ||
979 | dma_unmap_single(tup->uport.dev, tup->tx_dma_buf_phys, | ||
980 | UART_XMIT_SIZE, DMA_TO_DEVICE); | ||
981 | dma_chan = tup->tx_dma_chan; | ||
982 | tup->tx_dma_chan = NULL; | ||
983 | tup->tx_dma_buf_phys = 0; | ||
984 | tup->tx_dma_buf_virt = NULL; | ||
985 | } | ||
986 | dma_release_channel(dma_chan); | ||
987 | } | ||
988 | |||
989 | static int tegra_uart_startup(struct uart_port *u) | ||
990 | { | ||
991 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
992 | int ret; | ||
993 | |||
994 | ret = tegra_uart_dma_channel_allocate(tup, false); | ||
995 | if (ret < 0) { | ||
996 | dev_err(u->dev, "Tx Dma allocation failed, err = %d\n", ret); | ||
997 | return ret; | ||
998 | } | ||
999 | |||
1000 | ret = tegra_uart_dma_channel_allocate(tup, true); | ||
1001 | if (ret < 0) { | ||
1002 | dev_err(u->dev, "Rx Dma allocation failed, err = %d\n", ret); | ||
1003 | goto fail_rx_dma; | ||
1004 | } | ||
1005 | |||
1006 | ret = tegra_uart_hw_init(tup); | ||
1007 | if (ret < 0) { | ||
1008 | dev_err(u->dev, "Uart HW init failed, err = %d\n", ret); | ||
1009 | goto fail_hw_init; | ||
1010 | } | ||
1011 | |||
1012 | ret = request_irq(u->irq, tegra_uart_isr, IRQF_DISABLED, | ||
1013 | dev_name(u->dev), tup); | ||
1014 | if (ret < 0) { | ||
1015 | dev_err(u->dev, "Failed to register ISR for IRQ %d\n", u->irq); | ||
1016 | goto fail_hw_init; | ||
1017 | } | ||
1018 | return 0; | ||
1019 | |||
1020 | fail_hw_init: | ||
1021 | tegra_uart_dma_channel_free(tup, true); | ||
1022 | fail_rx_dma: | ||
1023 | tegra_uart_dma_channel_free(tup, false); | ||
1024 | return ret; | ||
1025 | } | ||
1026 | |||
1027 | static void tegra_uart_shutdown(struct uart_port *u) | ||
1028 | { | ||
1029 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1030 | |||
1031 | tegra_uart_hw_deinit(tup); | ||
1032 | |||
1033 | tup->rx_in_progress = 0; | ||
1034 | tup->tx_in_progress = 0; | ||
1035 | |||
1036 | tegra_uart_dma_channel_free(tup, true); | ||
1037 | tegra_uart_dma_channel_free(tup, false); | ||
1038 | free_irq(u->irq, tup); | ||
1039 | } | ||
1040 | |||
1041 | static void tegra_uart_enable_ms(struct uart_port *u) | ||
1042 | { | ||
1043 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1044 | |||
1045 | if (tup->enable_modem_interrupt) { | ||
1046 | tup->ier_shadow |= UART_IER_MSI; | ||
1047 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | static void tegra_uart_set_termios(struct uart_port *u, | ||
1052 | struct ktermios *termios, struct ktermios *oldtermios) | ||
1053 | { | ||
1054 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1055 | unsigned int baud; | ||
1056 | unsigned long flags; | ||
1057 | unsigned int lcr; | ||
1058 | int symb_bit = 1; | ||
1059 | struct clk *parent_clk = clk_get_parent(tup->uart_clk); | ||
1060 | unsigned long parent_clk_rate = clk_get_rate(parent_clk); | ||
1061 | int max_divider = (tup->cdata->support_clk_src_div) ? 0x7FFF : 0xFFFF; | ||
1062 | |||
1063 | max_divider *= 16; | ||
1064 | spin_lock_irqsave(&u->lock, flags); | ||
1065 | |||
1066 | /* Changing configuration, it is safe to stop any rx now */ | ||
1067 | if (tup->rts_active) | ||
1068 | set_rts(tup, false); | ||
1069 | |||
1070 | /* Clear all interrupts as configuration is going to be change */ | ||
1071 | tegra_uart_write(tup, tup->ier_shadow | UART_IER_RDI, UART_IER); | ||
1072 | tegra_uart_read(tup, UART_IER); | ||
1073 | tegra_uart_write(tup, 0, UART_IER); | ||
1074 | tegra_uart_read(tup, UART_IER); | ||
1075 | |||
1076 | /* Parity */ | ||
1077 | lcr = tup->lcr_shadow; | ||
1078 | lcr &= ~UART_LCR_PARITY; | ||
1079 | |||
1080 | /* CMSPAR isn't supported by this driver */ | ||
1081 | termios->c_cflag &= ~CMSPAR; | ||
1082 | |||
1083 | if ((termios->c_cflag & PARENB) == PARENB) { | ||
1084 | symb_bit++; | ||
1085 | if (termios->c_cflag & PARODD) { | ||
1086 | lcr |= UART_LCR_PARITY; | ||
1087 | lcr &= ~UART_LCR_EPAR; | ||
1088 | lcr &= ~UART_LCR_SPAR; | ||
1089 | } else { | ||
1090 | lcr |= UART_LCR_PARITY; | ||
1091 | lcr |= UART_LCR_EPAR; | ||
1092 | lcr &= ~UART_LCR_SPAR; | ||
1093 | } | ||
1094 | } | ||
1095 | |||
1096 | lcr &= ~UART_LCR_WLEN8; | ||
1097 | switch (termios->c_cflag & CSIZE) { | ||
1098 | case CS5: | ||
1099 | lcr |= UART_LCR_WLEN5; | ||
1100 | symb_bit += 5; | ||
1101 | break; | ||
1102 | case CS6: | ||
1103 | lcr |= UART_LCR_WLEN6; | ||
1104 | symb_bit += 6; | ||
1105 | break; | ||
1106 | case CS7: | ||
1107 | lcr |= UART_LCR_WLEN7; | ||
1108 | symb_bit += 7; | ||
1109 | break; | ||
1110 | default: | ||
1111 | lcr |= UART_LCR_WLEN8; | ||
1112 | symb_bit += 8; | ||
1113 | break; | ||
1114 | } | ||
1115 | |||
1116 | /* Stop bits */ | ||
1117 | if (termios->c_cflag & CSTOPB) { | ||
1118 | lcr |= UART_LCR_STOP; | ||
1119 | symb_bit += 2; | ||
1120 | } else { | ||
1121 | lcr &= ~UART_LCR_STOP; | ||
1122 | symb_bit++; | ||
1123 | } | ||
1124 | |||
1125 | tegra_uart_write(tup, lcr, UART_LCR); | ||
1126 | tup->lcr_shadow = lcr; | ||
1127 | tup->symb_bit = symb_bit; | ||
1128 | |||
1129 | /* Baud rate. */ | ||
1130 | baud = uart_get_baud_rate(u, termios, oldtermios, | ||
1131 | parent_clk_rate/max_divider, | ||
1132 | parent_clk_rate/16); | ||
1133 | spin_unlock_irqrestore(&u->lock, flags); | ||
1134 | tegra_set_baudrate(tup, baud); | ||
1135 | if (tty_termios_baud_rate(termios)) | ||
1136 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
1137 | spin_lock_irqsave(&u->lock, flags); | ||
1138 | |||
1139 | /* Flow control */ | ||
1140 | if (termios->c_cflag & CRTSCTS) { | ||
1141 | tup->mcr_shadow |= TEGRA_UART_MCR_CTS_EN; | ||
1142 | tup->mcr_shadow &= ~TEGRA_UART_MCR_RTS_EN; | ||
1143 | tegra_uart_write(tup, tup->mcr_shadow, UART_MCR); | ||
1144 | /* if top layer has asked to set rts active then do so here */ | ||
1145 | if (tup->rts_active) | ||
1146 | set_rts(tup, true); | ||
1147 | } else { | ||
1148 | tup->mcr_shadow &= ~TEGRA_UART_MCR_CTS_EN; | ||
1149 | tup->mcr_shadow &= ~TEGRA_UART_MCR_RTS_EN; | ||
1150 | tegra_uart_write(tup, tup->mcr_shadow, UART_MCR); | ||
1151 | } | ||
1152 | |||
1153 | /* update the port timeout based on new settings */ | ||
1154 | uart_update_timeout(u, termios->c_cflag, baud); | ||
1155 | |||
1156 | /* Make sure all write has completed */ | ||
1157 | tegra_uart_read(tup, UART_IER); | ||
1158 | |||
1159 | /* Reenable interrupt */ | ||
1160 | tegra_uart_write(tup, tup->ier_shadow, UART_IER); | ||
1161 | tegra_uart_read(tup, UART_IER); | ||
1162 | |||
1163 | spin_unlock_irqrestore(&u->lock, flags); | ||
1164 | return; | ||
1165 | } | ||
1166 | |||
1167 | /* | ||
1168 | * Flush any TX data submitted for DMA and PIO. Called when the | ||
1169 | * TX circular buffer is reset. | ||
1170 | */ | ||
1171 | static void tegra_uart_flush_buffer(struct uart_port *u) | ||
1172 | { | ||
1173 | struct tegra_uart_port *tup = to_tegra_uport(u); | ||
1174 | |||
1175 | tup->tx_bytes = 0; | ||
1176 | if (tup->tx_dma_chan) | ||
1177 | dmaengine_terminate_all(tup->tx_dma_chan); | ||
1178 | return; | ||
1179 | } | ||
1180 | |||
1181 | static const char *tegra_uart_type(struct uart_port *u) | ||
1182 | { | ||
1183 | return TEGRA_UART_TYPE; | ||
1184 | } | ||
1185 | |||
1186 | static struct uart_ops tegra_uart_ops = { | ||
1187 | .tx_empty = tegra_uart_tx_empty, | ||
1188 | .set_mctrl = tegra_uart_set_mctrl, | ||
1189 | .get_mctrl = tegra_uart_get_mctrl, | ||
1190 | .stop_tx = tegra_uart_stop_tx, | ||
1191 | .start_tx = tegra_uart_start_tx, | ||
1192 | .stop_rx = tegra_uart_stop_rx, | ||
1193 | .flush_buffer = tegra_uart_flush_buffer, | ||
1194 | .enable_ms = tegra_uart_enable_ms, | ||
1195 | .break_ctl = tegra_uart_break_ctl, | ||
1196 | .startup = tegra_uart_startup, | ||
1197 | .shutdown = tegra_uart_shutdown, | ||
1198 | .set_termios = tegra_uart_set_termios, | ||
1199 | .type = tegra_uart_type, | ||
1200 | .request_port = tegra_uart_request_port, | ||
1201 | .release_port = tegra_uart_release_port, | ||
1202 | }; | ||
1203 | |||
1204 | static struct uart_driver tegra_uart_driver = { | ||
1205 | .owner = THIS_MODULE, | ||
1206 | .driver_name = "tegra_hsuart", | ||
1207 | .dev_name = "ttyTHS", | ||
1208 | .cons = 0, | ||
1209 | .nr = TEGRA_UART_MAXIMUM, | ||
1210 | }; | ||
1211 | |||
1212 | static int tegra_uart_parse_dt(struct platform_device *pdev, | ||
1213 | struct tegra_uart_port *tup) | ||
1214 | { | ||
1215 | struct device_node *np = pdev->dev.of_node; | ||
1216 | u32 of_dma[2]; | ||
1217 | int port; | ||
1218 | |||
1219 | if (of_property_read_u32_array(np, "nvidia,dma-request-selector", | ||
1220 | of_dma, 2) >= 0) { | ||
1221 | tup->dma_req_sel = of_dma[1]; | ||
1222 | } else { | ||
1223 | dev_err(&pdev->dev, "missing dma requestor in device tree\n"); | ||
1224 | return -EINVAL; | ||
1225 | } | ||
1226 | |||
1227 | port = of_alias_get_id(np, "serial"); | ||
1228 | if (port < 0) { | ||
1229 | dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port); | ||
1230 | return port; | ||
1231 | } | ||
1232 | tup->uport.line = port; | ||
1233 | |||
1234 | tup->enable_modem_interrupt = of_property_read_bool(np, | ||
1235 | "nvidia,enable-modem-interrupt"); | ||
1236 | return 0; | ||
1237 | } | ||
1238 | |||
1239 | struct tegra_uart_chip_data tegra20_uart_chip_data = { | ||
1240 | .tx_fifo_full_status = false, | ||
1241 | .allow_txfifo_reset_fifo_mode = true, | ||
1242 | .support_clk_src_div = false, | ||
1243 | }; | ||
1244 | |||
1245 | struct tegra_uart_chip_data tegra30_uart_chip_data = { | ||
1246 | .tx_fifo_full_status = true, | ||
1247 | .allow_txfifo_reset_fifo_mode = false, | ||
1248 | .support_clk_src_div = true, | ||
1249 | }; | ||
1250 | |||
1251 | static struct of_device_id tegra_uart_of_match[] = { | ||
1252 | { | ||
1253 | .compatible = "nvidia,tegra30-hsuart", | ||
1254 | .data = &tegra30_uart_chip_data, | ||
1255 | }, { | ||
1256 | .compatible = "nvidia,tegra20-hsuart", | ||
1257 | .data = &tegra20_uart_chip_data, | ||
1258 | }, { | ||
1259 | }, | ||
1260 | }; | ||
1261 | MODULE_DEVICE_TABLE(of, tegra_uart_of_match); | ||
1262 | |||
1263 | static int tegra_uart_probe(struct platform_device *pdev) | ||
1264 | { | ||
1265 | struct tegra_uart_port *tup; | ||
1266 | struct uart_port *u; | ||
1267 | struct resource *resource; | ||
1268 | int ret; | ||
1269 | const struct tegra_uart_chip_data *cdata; | ||
1270 | const struct of_device_id *match; | ||
1271 | |||
1272 | match = of_match_device(tegra_uart_of_match, &pdev->dev); | ||
1273 | if (!match) { | ||
1274 | dev_err(&pdev->dev, "Error: No device match found\n"); | ||
1275 | return -ENODEV; | ||
1276 | } | ||
1277 | cdata = match->data; | ||
1278 | |||
1279 | tup = devm_kzalloc(&pdev->dev, sizeof(*tup), GFP_KERNEL); | ||
1280 | if (!tup) { | ||
1281 | dev_err(&pdev->dev, "Failed to allocate memory for tup\n"); | ||
1282 | return -ENOMEM; | ||
1283 | } | ||
1284 | |||
1285 | ret = tegra_uart_parse_dt(pdev, tup); | ||
1286 | if (ret < 0) | ||
1287 | return ret; | ||
1288 | |||
1289 | u = &tup->uport; | ||
1290 | u->dev = &pdev->dev; | ||
1291 | u->ops = &tegra_uart_ops; | ||
1292 | u->type = PORT_TEGRA; | ||
1293 | u->fifosize = 32; | ||
1294 | tup->cdata = cdata; | ||
1295 | |||
1296 | platform_set_drvdata(pdev, tup); | ||
1297 | resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1298 | if (!resource) { | ||
1299 | dev_err(&pdev->dev, "No IO memory resource\n"); | ||
1300 | return -ENODEV; | ||
1301 | } | ||
1302 | |||
1303 | u->mapbase = resource->start; | ||
1304 | u->membase = devm_request_and_ioremap(&pdev->dev, resource); | ||
1305 | if (!u->membase) { | ||
1306 | dev_err(&pdev->dev, "memregion/iomap address req failed\n"); | ||
1307 | return -EADDRNOTAVAIL; | ||
1308 | } | ||
1309 | |||
1310 | tup->uart_clk = devm_clk_get(&pdev->dev, NULL); | ||
1311 | if (IS_ERR(tup->uart_clk)) { | ||
1312 | dev_err(&pdev->dev, "Couldn't get the clock\n"); | ||
1313 | return PTR_ERR(tup->uart_clk); | ||
1314 | } | ||
1315 | |||
1316 | u->iotype = UPIO_MEM32; | ||
1317 | u->irq = platform_get_irq(pdev, 0); | ||
1318 | u->regshift = 2; | ||
1319 | ret = uart_add_one_port(&tegra_uart_driver, u); | ||
1320 | if (ret < 0) { | ||
1321 | dev_err(&pdev->dev, "Failed to add uart port, err %d\n", ret); | ||
1322 | return ret; | ||
1323 | } | ||
1324 | return ret; | ||
1325 | } | ||
1326 | |||
1327 | static int tegra_uart_remove(struct platform_device *pdev) | ||
1328 | { | ||
1329 | struct tegra_uart_port *tup = platform_get_drvdata(pdev); | ||
1330 | struct uart_port *u = &tup->uport; | ||
1331 | |||
1332 | uart_remove_one_port(&tegra_uart_driver, u); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | #ifdef CONFIG_PM_SLEEP | ||
1337 | static int tegra_uart_suspend(struct device *dev) | ||
1338 | { | ||
1339 | struct tegra_uart_port *tup = dev_get_drvdata(dev); | ||
1340 | struct uart_port *u = &tup->uport; | ||
1341 | |||
1342 | return uart_suspend_port(&tegra_uart_driver, u); | ||
1343 | } | ||
1344 | |||
1345 | static int tegra_uart_resume(struct device *dev) | ||
1346 | { | ||
1347 | struct tegra_uart_port *tup = dev_get_drvdata(dev); | ||
1348 | struct uart_port *u = &tup->uport; | ||
1349 | |||
1350 | return uart_resume_port(&tegra_uart_driver, u); | ||
1351 | } | ||
1352 | #endif | ||
1353 | |||
1354 | static const struct dev_pm_ops tegra_uart_pm_ops = { | ||
1355 | SET_SYSTEM_SLEEP_PM_OPS(tegra_uart_suspend, tegra_uart_resume) | ||
1356 | }; | ||
1357 | |||
1358 | static struct platform_driver tegra_uart_platform_driver = { | ||
1359 | .probe = tegra_uart_probe, | ||
1360 | .remove = tegra_uart_remove, | ||
1361 | .driver = { | ||
1362 | .name = "serial-tegra", | ||
1363 | .of_match_table = tegra_uart_of_match, | ||
1364 | .pm = &tegra_uart_pm_ops, | ||
1365 | }, | ||
1366 | }; | ||
1367 | |||
1368 | static int __init tegra_uart_init(void) | ||
1369 | { | ||
1370 | int ret; | ||
1371 | |||
1372 | ret = uart_register_driver(&tegra_uart_driver); | ||
1373 | if (ret < 0) { | ||
1374 | pr_err("Could not register %s driver\n", | ||
1375 | tegra_uart_driver.driver_name); | ||
1376 | return ret; | ||
1377 | } | ||
1378 | |||
1379 | ret = platform_driver_register(&tegra_uart_platform_driver); | ||
1380 | if (ret < 0) { | ||
1381 | pr_err("Uart platfrom driver register failed, e = %d\n", ret); | ||
1382 | uart_unregister_driver(&tegra_uart_driver); | ||
1383 | return ret; | ||
1384 | } | ||
1385 | return 0; | ||
1386 | } | ||
1387 | |||
1388 | static void __exit tegra_uart_exit(void) | ||
1389 | { | ||
1390 | pr_info("Unloading tegra uart driver\n"); | ||
1391 | platform_driver_unregister(&tegra_uart_platform_driver); | ||
1392 | uart_unregister_driver(&tegra_uart_driver); | ||
1393 | } | ||
1394 | |||
1395 | module_init(tegra_uart_init); | ||
1396 | module_exit(tegra_uart_exit); | ||
1397 | |||
1398 | MODULE_ALIAS("platform:serial-tegra"); | ||
1399 | MODULE_DESCRIPTION("High speed UART driver for tegra chipset"); | ||
1400 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
1401 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2c7230aaefd4..a400002dfa84 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -59,7 +59,8 @@ static struct lock_class_key port_lock_key; | |||
59 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | 59 | static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, |
60 | struct ktermios *old_termios); | 60 | struct ktermios *old_termios); |
61 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); | 61 | static void uart_wait_until_sent(struct tty_struct *tty, int timeout); |
62 | static void uart_change_pm(struct uart_state *state, int pm_state); | 62 | static void uart_change_pm(struct uart_state *state, |
63 | enum uart_pm_state pm_state); | ||
63 | 64 | ||
64 | static void uart_port_shutdown(struct tty_port *port); | 65 | static void uart_port_shutdown(struct tty_port *port); |
65 | 66 | ||
@@ -866,9 +867,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
866 | port->closing_wait = closing_wait; | 867 | port->closing_wait = closing_wait; |
867 | if (new_info->xmit_fifo_size) | 868 | if (new_info->xmit_fifo_size) |
868 | uport->fifosize = new_info->xmit_fifo_size; | 869 | uport->fifosize = new_info->xmit_fifo_size; |
869 | if (port->tty) | 870 | port->low_latency = (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; |
870 | port->tty->low_latency = | ||
871 | (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
872 | 871 | ||
873 | check_and_exit: | 872 | check_and_exit: |
874 | retval = 0; | 873 | retval = 0; |
@@ -1308,9 +1307,10 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1308 | } | 1307 | } |
1309 | 1308 | ||
1310 | /* | 1309 | /* |
1311 | * In 2.4.5, calls to this will be serialized via the BKL in | 1310 | * Calls to uart_close() are serialised via the tty_lock in |
1312 | * linux/drivers/char/tty_io.c:tty_release() | 1311 | * drivers/tty/tty_io.c:tty_release() |
1313 | * linux/drivers/char/tty_io.c:do_tty_handup() | 1312 | * drivers/tty/tty_io.c:do_tty_hangup() |
1313 | * This runs from a workqueue and can sleep for a _short_ time only. | ||
1314 | */ | 1314 | */ |
1315 | static void uart_close(struct tty_struct *tty, struct file *filp) | 1315 | static void uart_close(struct tty_struct *tty, struct file *filp) |
1316 | { | 1316 | { |
@@ -1365,7 +1365,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) | |||
1365 | spin_lock_irqsave(&port->lock, flags); | 1365 | spin_lock_irqsave(&port->lock, flags); |
1366 | } else if (!uart_console(uport)) { | 1366 | } else if (!uart_console(uport)) { |
1367 | spin_unlock_irqrestore(&port->lock, flags); | 1367 | spin_unlock_irqrestore(&port->lock, flags); |
1368 | uart_change_pm(state, 3); | 1368 | uart_change_pm(state, UART_PM_STATE_OFF); |
1369 | spin_lock_irqsave(&port->lock, flags); | 1369 | spin_lock_irqsave(&port->lock, flags); |
1370 | } | 1370 | } |
1371 | 1371 | ||
@@ -1437,10 +1437,9 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | /* | 1439 | /* |
1440 | * This is called with the BKL held in | 1440 | * Calls to uart_hangup() are serialised by the tty_lock in |
1441 | * linux/drivers/char/tty_io.c:do_tty_hangup() | 1441 | * drivers/tty/tty_io.c:do_tty_hangup() |
1442 | * We're called from the eventd thread, so we can sleep for | 1442 | * This runs from a workqueue and can sleep for a _short_ time only. |
1443 | * a _short_ time only. | ||
1444 | */ | 1443 | */ |
1445 | static void uart_hangup(struct tty_struct *tty) | 1444 | static void uart_hangup(struct tty_struct *tty) |
1446 | { | 1445 | { |
@@ -1521,8 +1520,8 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) | |||
1521 | } | 1520 | } |
1522 | 1521 | ||
1523 | /* | 1522 | /* |
1524 | * calls to uart_open are serialised by the BKL in | 1523 | * Calls to uart_open are serialised by the tty_lock in |
1525 | * fs/char_dev.c:chrdev_open() | 1524 | * drivers/tty/tty_io.c:tty_open() |
1526 | * Note that if this fails, then uart_close() _will_ be called. | 1525 | * Note that if this fails, then uart_close() _will_ be called. |
1527 | * | 1526 | * |
1528 | * In time, we want to scrap the "opening nonpresent ports" | 1527 | * In time, we want to scrap the "opening nonpresent ports" |
@@ -1564,7 +1563,8 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1564 | */ | 1563 | */ |
1565 | tty->driver_data = state; | 1564 | tty->driver_data = state; |
1566 | state->uart_port->state = state; | 1565 | state->uart_port->state = state; |
1567 | tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; | 1566 | state->port.low_latency = |
1567 | (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0; | ||
1568 | tty_port_tty_set(port, tty); | 1568 | tty_port_tty_set(port, tty); |
1569 | 1569 | ||
1570 | /* | 1570 | /* |
@@ -1579,7 +1579,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1579 | * Make sure the device is in D0 state. | 1579 | * Make sure the device is in D0 state. |
1580 | */ | 1580 | */ |
1581 | if (port->count == 1) | 1581 | if (port->count == 1) |
1582 | uart_change_pm(state, 0); | 1582 | uart_change_pm(state, UART_PM_STATE_ON); |
1583 | 1583 | ||
1584 | /* | 1584 | /* |
1585 | * Start up the serial port. | 1585 | * Start up the serial port. |
@@ -1620,7 +1620,7 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1620 | { | 1620 | { |
1621 | struct uart_state *state = drv->state + i; | 1621 | struct uart_state *state = drv->state + i; |
1622 | struct tty_port *port = &state->port; | 1622 | struct tty_port *port = &state->port; |
1623 | int pm_state; | 1623 | enum uart_pm_state pm_state; |
1624 | struct uart_port *uport = state->uart_port; | 1624 | struct uart_port *uport = state->uart_port; |
1625 | char stat_buf[32]; | 1625 | char stat_buf[32]; |
1626 | unsigned int status; | 1626 | unsigned int status; |
@@ -1645,12 +1645,12 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i) | |||
1645 | if (capable(CAP_SYS_ADMIN)) { | 1645 | if (capable(CAP_SYS_ADMIN)) { |
1646 | mutex_lock(&port->mutex); | 1646 | mutex_lock(&port->mutex); |
1647 | pm_state = state->pm_state; | 1647 | pm_state = state->pm_state; |
1648 | if (pm_state) | 1648 | if (pm_state != UART_PM_STATE_ON) |
1649 | uart_change_pm(state, 0); | 1649 | uart_change_pm(state, UART_PM_STATE_ON); |
1650 | spin_lock_irq(&uport->lock); | 1650 | spin_lock_irq(&uport->lock); |
1651 | status = uport->ops->get_mctrl(uport); | 1651 | status = uport->ops->get_mctrl(uport); |
1652 | spin_unlock_irq(&uport->lock); | 1652 | spin_unlock_irq(&uport->lock); |
1653 | if (pm_state) | 1653 | if (pm_state != UART_PM_STATE_ON) |
1654 | uart_change_pm(state, pm_state); | 1654 | uart_change_pm(state, pm_state); |
1655 | mutex_unlock(&port->mutex); | 1655 | mutex_unlock(&port->mutex); |
1656 | 1656 | ||
@@ -1897,7 +1897,8 @@ EXPORT_SYMBOL_GPL(uart_set_options); | |||
1897 | * | 1897 | * |
1898 | * Locking: port->mutex has to be held | 1898 | * Locking: port->mutex has to be held |
1899 | */ | 1899 | */ |
1900 | static void uart_change_pm(struct uart_state *state, int pm_state) | 1900 | static void uart_change_pm(struct uart_state *state, |
1901 | enum uart_pm_state pm_state) | ||
1901 | { | 1902 | { |
1902 | struct uart_port *port = state->uart_port; | 1903 | struct uart_port *port = state->uart_port; |
1903 | 1904 | ||
@@ -1982,7 +1983,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) | |||
1982 | console_stop(uport->cons); | 1983 | console_stop(uport->cons); |
1983 | 1984 | ||
1984 | if (console_suspend_enabled || !uart_console(uport)) | 1985 | if (console_suspend_enabled || !uart_console(uport)) |
1985 | uart_change_pm(state, 3); | 1986 | uart_change_pm(state, UART_PM_STATE_OFF); |
1986 | 1987 | ||
1987 | mutex_unlock(&port->mutex); | 1988 | mutex_unlock(&port->mutex); |
1988 | 1989 | ||
@@ -2027,7 +2028,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2027 | termios = port->tty->termios; | 2028 | termios = port->tty->termios; |
2028 | 2029 | ||
2029 | if (console_suspend_enabled) | 2030 | if (console_suspend_enabled) |
2030 | uart_change_pm(state, 0); | 2031 | uart_change_pm(state, UART_PM_STATE_ON); |
2031 | uport->ops->set_termios(uport, &termios, NULL); | 2032 | uport->ops->set_termios(uport, &termios, NULL); |
2032 | if (console_suspend_enabled) | 2033 | if (console_suspend_enabled) |
2033 | console_start(uport->cons); | 2034 | console_start(uport->cons); |
@@ -2037,7 +2038,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
2037 | const struct uart_ops *ops = uport->ops; | 2038 | const struct uart_ops *ops = uport->ops; |
2038 | int ret; | 2039 | int ret; |
2039 | 2040 | ||
2040 | uart_change_pm(state, 0); | 2041 | uart_change_pm(state, UART_PM_STATE_ON); |
2041 | spin_lock_irq(&uport->lock); | 2042 | spin_lock_irq(&uport->lock); |
2042 | ops->set_mctrl(uport, 0); | 2043 | ops->set_mctrl(uport, 0); |
2043 | spin_unlock_irq(&uport->lock); | 2044 | spin_unlock_irq(&uport->lock); |
@@ -2137,7 +2138,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
2137 | uart_report_port(drv, port); | 2138 | uart_report_port(drv, port); |
2138 | 2139 | ||
2139 | /* Power up port for set_mctrl() */ | 2140 | /* Power up port for set_mctrl() */ |
2140 | uart_change_pm(state, 0); | 2141 | uart_change_pm(state, UART_PM_STATE_ON); |
2141 | 2142 | ||
2142 | /* | 2143 | /* |
2143 | * Ensure that the modem control lines are de-activated. | 2144 | * Ensure that the modem control lines are de-activated. |
@@ -2161,7 +2162,7 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, | |||
2161 | * console if we have one. | 2162 | * console if we have one. |
2162 | */ | 2163 | */ |
2163 | if (!uart_console(port)) | 2164 | if (!uart_console(port)) |
2164 | uart_change_pm(state, 3); | 2165 | uart_change_pm(state, UART_PM_STATE_OFF); |
2165 | } | 2166 | } |
2166 | } | 2167 | } |
2167 | 2168 | ||
@@ -2588,7 +2589,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2588 | } | 2589 | } |
2589 | 2590 | ||
2590 | state->uart_port = uport; | 2591 | state->uart_port = uport; |
2591 | state->pm_state = -1; | 2592 | state->pm_state = UART_PM_STATE_UNDEFINED; |
2592 | 2593 | ||
2593 | uport->cons = drv->cons; | 2594 | uport->cons = drv->cons; |
2594 | uport->state = state; | 2595 | uport->state = state; |
@@ -2642,6 +2643,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2642 | { | 2643 | { |
2643 | struct uart_state *state = drv->state + uport->line; | 2644 | struct uart_state *state = drv->state + uport->line; |
2644 | struct tty_port *port = &state->port; | 2645 | struct tty_port *port = &state->port; |
2646 | int ret = 0; | ||
2645 | 2647 | ||
2646 | BUG_ON(in_interrupt()); | 2648 | BUG_ON(in_interrupt()); |
2647 | 2649 | ||
@@ -2656,6 +2658,11 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2656 | * succeeding while we shut down the port. | 2658 | * succeeding while we shut down the port. |
2657 | */ | 2659 | */ |
2658 | mutex_lock(&port->mutex); | 2660 | mutex_lock(&port->mutex); |
2661 | if (!state->uart_port) { | ||
2662 | mutex_unlock(&port->mutex); | ||
2663 | ret = -EINVAL; | ||
2664 | goto out; | ||
2665 | } | ||
2659 | uport->flags |= UPF_DEAD; | 2666 | uport->flags |= UPF_DEAD; |
2660 | mutex_unlock(&port->mutex); | 2667 | mutex_unlock(&port->mutex); |
2661 | 2668 | ||
@@ -2679,9 +2686,10 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2679 | uport->type = PORT_UNKNOWN; | 2686 | uport->type = PORT_UNKNOWN; |
2680 | 2687 | ||
2681 | state->uart_port = NULL; | 2688 | state->uart_port = NULL; |
2689 | out: | ||
2682 | mutex_unlock(&port_mutex); | 2690 | mutex_unlock(&port_mutex); |
2683 | 2691 | ||
2684 | return 0; | 2692 | return ret; |
2685 | } | 2693 | } |
2686 | 2694 | ||
2687 | /* | 2695 | /* |
@@ -2715,22 +2723,17 @@ EXPORT_SYMBOL(uart_match_port); | |||
2715 | */ | 2723 | */ |
2716 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | 2724 | void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) |
2717 | { | 2725 | { |
2718 | struct uart_state *state = uport->state; | 2726 | struct tty_port *port = &uport->state->port; |
2719 | struct tty_port *port = &state->port; | ||
2720 | struct tty_ldisc *ld = NULL; | ||
2721 | struct pps_event_time ts; | ||
2722 | struct tty_struct *tty = port->tty; | 2727 | struct tty_struct *tty = port->tty; |
2728 | struct tty_ldisc *ld = tty ? tty_ldisc_ref(tty) : NULL; | ||
2723 | 2729 | ||
2724 | if (tty) | 2730 | if (ld) { |
2725 | ld = tty_ldisc_ref(tty); | 2731 | if (ld->ops->dcd_change) |
2726 | if (ld && ld->ops->dcd_change) | 2732 | ld->ops->dcd_change(tty, status); |
2727 | pps_get_ts(&ts); | 2733 | tty_ldisc_deref(ld); |
2734 | } | ||
2728 | 2735 | ||
2729 | uport->icount.dcd++; | 2736 | uport->icount.dcd++; |
2730 | #ifdef CONFIG_HARD_PPS | ||
2731 | if ((uport->flags & UPF_HARDPPS_CD) && status) | ||
2732 | hardpps(); | ||
2733 | #endif | ||
2734 | 2737 | ||
2735 | if (port->flags & ASYNC_CHECK_CD) { | 2738 | if (port->flags & ASYNC_CHECK_CD) { |
2736 | if (status) | 2739 | if (status) |
@@ -2738,11 +2741,6 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) | |||
2738 | else if (tty) | 2741 | else if (tty) |
2739 | tty_hangup(tty); | 2742 | tty_hangup(tty); |
2740 | } | 2743 | } |
2741 | |||
2742 | if (ld && ld->ops->dcd_change) | ||
2743 | ld->ops->dcd_change(tty, status, &ts); | ||
2744 | if (ld) | ||
2745 | tty_ldisc_deref(ld); | ||
2746 | } | 2744 | } |
2747 | EXPORT_SYMBOL_GPL(uart_handle_dcd_change); | 2745 | EXPORT_SYMBOL_GPL(uart_handle_dcd_change); |
2748 | 2746 | ||
@@ -2790,10 +2788,10 @@ EXPORT_SYMBOL_GPL(uart_handle_cts_change); | |||
2790 | void uart_insert_char(struct uart_port *port, unsigned int status, | 2788 | void uart_insert_char(struct uart_port *port, unsigned int status, |
2791 | unsigned int overrun, unsigned int ch, unsigned int flag) | 2789 | unsigned int overrun, unsigned int ch, unsigned int flag) |
2792 | { | 2790 | { |
2793 | struct tty_struct *tty = port->state->port.tty; | 2791 | struct tty_port *tport = &port->state->port; |
2794 | 2792 | ||
2795 | if ((status & port->ignore_status_mask & ~overrun) == 0) | 2793 | if ((status & port->ignore_status_mask & ~overrun) == 0) |
2796 | if (tty_insert_flip_char(tty, ch, flag) == 0) | 2794 | if (tty_insert_flip_char(tport, ch, flag) == 0) |
2797 | ++port->icount.buf_overrun; | 2795 | ++port->icount.buf_overrun; |
2798 | 2796 | ||
2799 | /* | 2797 | /* |
@@ -2801,7 +2799,7 @@ void uart_insert_char(struct uart_port *port, unsigned int status, | |||
2801 | * it doesn't affect the current character. | 2799 | * it doesn't affect the current character. |
2802 | */ | 2800 | */ |
2803 | if (status & ~port->ignore_status_mask & overrun) | 2801 | if (status & ~port->ignore_status_mask & overrun) |
2804 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN) == 0) | 2802 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN) == 0) |
2805 | ++port->icount.buf_overrun; | 2803 | ++port->icount.buf_overrun; |
2806 | } | 2804 | } |
2807 | EXPORT_SYMBOL_GPL(uart_insert_char); | 2805 | EXPORT_SYMBOL_GPL(uart_insert_char); |
diff --git a/drivers/tty/serial/serial_ks8695.c b/drivers/tty/serial/serial_ks8695.c index 9bd004f9da89..e1caa99e3d3b 100644 --- a/drivers/tty/serial/serial_ks8695.c +++ b/drivers/tty/serial/serial_ks8695.c | |||
@@ -153,7 +153,6 @@ static void ks8695uart_disable_ms(struct uart_port *port) | |||
153 | static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) | 153 | static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) |
154 | { | 154 | { |
155 | struct uart_port *port = dev_id; | 155 | struct uart_port *port = dev_id; |
156 | struct tty_struct *tty = port->state->port.tty; | ||
157 | unsigned int status, ch, lsr, flg, max_count = 256; | 156 | unsigned int status, ch, lsr, flg, max_count = 256; |
158 | 157 | ||
159 | status = UART_GET_LSR(port); /* clears pending LSR interrupts */ | 158 | status = UART_GET_LSR(port); /* clears pending LSR interrupts */ |
@@ -200,7 +199,7 @@ static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id) | |||
200 | ignore_char: | 199 | ignore_char: |
201 | status = UART_GET_LSR(port); | 200 | status = UART_GET_LSR(port); |
202 | } | 201 | } |
203 | tty_flip_buffer_push(tty); | 202 | tty_flip_buffer_push(&port->state->port); |
204 | 203 | ||
205 | return IRQ_HANDLED; | 204 | return IRQ_HANDLED; |
206 | } | 205 | } |
diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index b52b21aeb250..fe48a0c2b4ca 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c | |||
@@ -277,7 +277,6 @@ static void serial_txx9_initialize(struct uart_port *port) | |||
277 | static inline void | 277 | static inline void |
278 | receive_chars(struct uart_txx9_port *up, unsigned int *status) | 278 | receive_chars(struct uart_txx9_port *up, unsigned int *status) |
279 | { | 279 | { |
280 | struct tty_struct *tty = up->port.state->port.tty; | ||
281 | unsigned char ch; | 280 | unsigned char ch; |
282 | unsigned int disr = *status; | 281 | unsigned int disr = *status; |
283 | int max_count = 256; | 282 | int max_count = 256; |
@@ -346,7 +345,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status) | |||
346 | disr = sio_in(up, TXX9_SIDISR); | 345 | disr = sio_in(up, TXX9_SIDISR); |
347 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); | 346 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); |
348 | spin_unlock(&up->port.lock); | 347 | spin_unlock(&up->port.lock); |
349 | tty_flip_buffer_push(tty); | 348 | tty_flip_buffer_push(&up->port.state->port); |
350 | spin_lock(&up->port.lock); | 349 | spin_lock(&up->port.lock); |
351 | *status = disr; | 350 | *status = disr; |
352 | } | 351 | } |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 61477567423f..156418619949 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -596,7 +596,7 @@ static void sci_transmit_chars(struct uart_port *port) | |||
596 | static void sci_receive_chars(struct uart_port *port) | 596 | static void sci_receive_chars(struct uart_port *port) |
597 | { | 597 | { |
598 | struct sci_port *sci_port = to_sci_port(port); | 598 | struct sci_port *sci_port = to_sci_port(port); |
599 | struct tty_struct *tty = port->state->port.tty; | 599 | struct tty_port *tport = &port->state->port; |
600 | int i, count, copied = 0; | 600 | int i, count, copied = 0; |
601 | unsigned short status; | 601 | unsigned short status; |
602 | unsigned char flag; | 602 | unsigned char flag; |
@@ -607,7 +607,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
607 | 607 | ||
608 | while (1) { | 608 | while (1) { |
609 | /* Don't copy more bytes than there is room for in the buffer */ | 609 | /* Don't copy more bytes than there is room for in the buffer */ |
610 | count = tty_buffer_request_room(tty, sci_rxfill(port)); | 610 | count = tty_buffer_request_room(tport, sci_rxfill(port)); |
611 | 611 | ||
612 | /* If for any reason we can't copy more data, we're done! */ | 612 | /* If for any reason we can't copy more data, we're done! */ |
613 | if (count == 0) | 613 | if (count == 0) |
@@ -619,7 +619,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
619 | sci_port->break_flag) | 619 | sci_port->break_flag) |
620 | count = 0; | 620 | count = 0; |
621 | else | 621 | else |
622 | tty_insert_flip_char(tty, c, TTY_NORMAL); | 622 | tty_insert_flip_char(tport, c, TTY_NORMAL); |
623 | } else { | 623 | } else { |
624 | for (i = 0; i < count; i++) { | 624 | for (i = 0; i < count; i++) { |
625 | char c = serial_port_in(port, SCxRDR); | 625 | char c = serial_port_in(port, SCxRDR); |
@@ -661,7 +661,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
661 | } else | 661 | } else |
662 | flag = TTY_NORMAL; | 662 | flag = TTY_NORMAL; |
663 | 663 | ||
664 | tty_insert_flip_char(tty, c, flag); | 664 | tty_insert_flip_char(tport, c, flag); |
665 | } | 665 | } |
666 | } | 666 | } |
667 | 667 | ||
@@ -674,7 +674,7 @@ static void sci_receive_chars(struct uart_port *port) | |||
674 | 674 | ||
675 | if (copied) { | 675 | if (copied) { |
676 | /* Tell the rest of the system the news. New characters! */ | 676 | /* Tell the rest of the system the news. New characters! */ |
677 | tty_flip_buffer_push(tty); | 677 | tty_flip_buffer_push(tport); |
678 | } else { | 678 | } else { |
679 | serial_port_in(port, SCxSR); /* dummy read */ | 679 | serial_port_in(port, SCxSR); /* dummy read */ |
680 | serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); | 680 | serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); |
@@ -720,7 +720,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
720 | { | 720 | { |
721 | int copied = 0; | 721 | int copied = 0; |
722 | unsigned short status = serial_port_in(port, SCxSR); | 722 | unsigned short status = serial_port_in(port, SCxSR); |
723 | struct tty_struct *tty = port->state->port.tty; | 723 | struct tty_port *tport = &port->state->port; |
724 | struct sci_port *s = to_sci_port(port); | 724 | struct sci_port *s = to_sci_port(port); |
725 | 725 | ||
726 | /* | 726 | /* |
@@ -731,7 +731,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
731 | port->icount.overrun++; | 731 | port->icount.overrun++; |
732 | 732 | ||
733 | /* overrun error */ | 733 | /* overrun error */ |
734 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) | 734 | if (tty_insert_flip_char(tport, 0, TTY_OVERRUN)) |
735 | copied++; | 735 | copied++; |
736 | 736 | ||
737 | dev_notice(port->dev, "overrun error"); | 737 | dev_notice(port->dev, "overrun error"); |
@@ -755,7 +755,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
755 | 755 | ||
756 | dev_dbg(port->dev, "BREAK detected\n"); | 756 | dev_dbg(port->dev, "BREAK detected\n"); |
757 | 757 | ||
758 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) | 758 | if (tty_insert_flip_char(tport, 0, TTY_BREAK)) |
759 | copied++; | 759 | copied++; |
760 | } | 760 | } |
761 | 761 | ||
@@ -763,7 +763,7 @@ static int sci_handle_errors(struct uart_port *port) | |||
763 | /* frame error */ | 763 | /* frame error */ |
764 | port->icount.frame++; | 764 | port->icount.frame++; |
765 | 765 | ||
766 | if (tty_insert_flip_char(tty, 0, TTY_FRAME)) | 766 | if (tty_insert_flip_char(tport, 0, TTY_FRAME)) |
767 | copied++; | 767 | copied++; |
768 | 768 | ||
769 | dev_notice(port->dev, "frame error\n"); | 769 | dev_notice(port->dev, "frame error\n"); |
@@ -774,21 +774,21 @@ static int sci_handle_errors(struct uart_port *port) | |||
774 | /* parity error */ | 774 | /* parity error */ |
775 | port->icount.parity++; | 775 | port->icount.parity++; |
776 | 776 | ||
777 | if (tty_insert_flip_char(tty, 0, TTY_PARITY)) | 777 | if (tty_insert_flip_char(tport, 0, TTY_PARITY)) |
778 | copied++; | 778 | copied++; |
779 | 779 | ||
780 | dev_notice(port->dev, "parity error"); | 780 | dev_notice(port->dev, "parity error"); |
781 | } | 781 | } |
782 | 782 | ||
783 | if (copied) | 783 | if (copied) |
784 | tty_flip_buffer_push(tty); | 784 | tty_flip_buffer_push(tport); |
785 | 785 | ||
786 | return copied; | 786 | return copied; |
787 | } | 787 | } |
788 | 788 | ||
789 | static int sci_handle_fifo_overrun(struct uart_port *port) | 789 | static int sci_handle_fifo_overrun(struct uart_port *port) |
790 | { | 790 | { |
791 | struct tty_struct *tty = port->state->port.tty; | 791 | struct tty_port *tport = &port->state->port; |
792 | struct sci_port *s = to_sci_port(port); | 792 | struct sci_port *s = to_sci_port(port); |
793 | struct plat_sci_reg *reg; | 793 | struct plat_sci_reg *reg; |
794 | int copied = 0; | 794 | int copied = 0; |
@@ -802,8 +802,8 @@ static int sci_handle_fifo_overrun(struct uart_port *port) | |||
802 | 802 | ||
803 | port->icount.overrun++; | 803 | port->icount.overrun++; |
804 | 804 | ||
805 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 805 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
806 | tty_flip_buffer_push(tty); | 806 | tty_flip_buffer_push(tport); |
807 | 807 | ||
808 | dev_notice(port->dev, "overrun error\n"); | 808 | dev_notice(port->dev, "overrun error\n"); |
809 | copied++; | 809 | copied++; |
@@ -816,7 +816,7 @@ static int sci_handle_breaks(struct uart_port *port) | |||
816 | { | 816 | { |
817 | int copied = 0; | 817 | int copied = 0; |
818 | unsigned short status = serial_port_in(port, SCxSR); | 818 | unsigned short status = serial_port_in(port, SCxSR); |
819 | struct tty_struct *tty = port->state->port.tty; | 819 | struct tty_port *tport = &port->state->port; |
820 | struct sci_port *s = to_sci_port(port); | 820 | struct sci_port *s = to_sci_port(port); |
821 | 821 | ||
822 | if (uart_handle_break(port)) | 822 | if (uart_handle_break(port)) |
@@ -831,14 +831,14 @@ static int sci_handle_breaks(struct uart_port *port) | |||
831 | port->icount.brk++; | 831 | port->icount.brk++; |
832 | 832 | ||
833 | /* Notify of BREAK */ | 833 | /* Notify of BREAK */ |
834 | if (tty_insert_flip_char(tty, 0, TTY_BREAK)) | 834 | if (tty_insert_flip_char(tport, 0, TTY_BREAK)) |
835 | copied++; | 835 | copied++; |
836 | 836 | ||
837 | dev_dbg(port->dev, "BREAK detected\n"); | 837 | dev_dbg(port->dev, "BREAK detected\n"); |
838 | } | 838 | } |
839 | 839 | ||
840 | if (copied) | 840 | if (copied) |
841 | tty_flip_buffer_push(tty); | 841 | tty_flip_buffer_push(tport); |
842 | 842 | ||
843 | copied += sci_handle_fifo_overrun(port); | 843 | copied += sci_handle_fifo_overrun(port); |
844 | 844 | ||
@@ -1259,13 +1259,13 @@ static void sci_dma_tx_complete(void *arg) | |||
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | /* Locking: called with port lock held */ | 1261 | /* Locking: called with port lock held */ |
1262 | static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | 1262 | static int sci_dma_rx_push(struct sci_port *s, size_t count) |
1263 | size_t count) | ||
1264 | { | 1263 | { |
1265 | struct uart_port *port = &s->port; | 1264 | struct uart_port *port = &s->port; |
1265 | struct tty_port *tport = &port->state->port; | ||
1266 | int i, active, room; | 1266 | int i, active, room; |
1267 | 1267 | ||
1268 | room = tty_buffer_request_room(tty, count); | 1268 | room = tty_buffer_request_room(tport, count); |
1269 | 1269 | ||
1270 | if (s->active_rx == s->cookie_rx[0]) { | 1270 | if (s->active_rx == s->cookie_rx[0]) { |
1271 | active = 0; | 1271 | active = 0; |
@@ -1283,7 +1283,7 @@ static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | |||
1283 | return room; | 1283 | return room; |
1284 | 1284 | ||
1285 | for (i = 0; i < room; i++) | 1285 | for (i = 0; i < room; i++) |
1286 | tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i], | 1286 | tty_insert_flip_char(tport, ((u8 *)sg_virt(&s->sg_rx[active]))[i], |
1287 | TTY_NORMAL); | 1287 | TTY_NORMAL); |
1288 | 1288 | ||
1289 | port->icount.rx += room; | 1289 | port->icount.rx += room; |
@@ -1295,7 +1295,6 @@ static void sci_dma_rx_complete(void *arg) | |||
1295 | { | 1295 | { |
1296 | struct sci_port *s = arg; | 1296 | struct sci_port *s = arg; |
1297 | struct uart_port *port = &s->port; | 1297 | struct uart_port *port = &s->port; |
1298 | struct tty_struct *tty = port->state->port.tty; | ||
1299 | unsigned long flags; | 1298 | unsigned long flags; |
1300 | int count; | 1299 | int count; |
1301 | 1300 | ||
@@ -1303,14 +1302,14 @@ static void sci_dma_rx_complete(void *arg) | |||
1303 | 1302 | ||
1304 | spin_lock_irqsave(&port->lock, flags); | 1303 | spin_lock_irqsave(&port->lock, flags); |
1305 | 1304 | ||
1306 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); | 1305 | count = sci_dma_rx_push(s, s->buf_len_rx); |
1307 | 1306 | ||
1308 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); | 1307 | mod_timer(&s->rx_timer, jiffies + s->rx_timeout); |
1309 | 1308 | ||
1310 | spin_unlock_irqrestore(&port->lock, flags); | 1309 | spin_unlock_irqrestore(&port->lock, flags); |
1311 | 1310 | ||
1312 | if (count) | 1311 | if (count) |
1313 | tty_flip_buffer_push(tty); | 1312 | tty_flip_buffer_push(&port->state->port); |
1314 | 1313 | ||
1315 | schedule_work(&s->work_rx); | 1314 | schedule_work(&s->work_rx); |
1316 | } | 1315 | } |
@@ -1404,7 +1403,6 @@ static void work_fn_rx(struct work_struct *work) | |||
1404 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != | 1403 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != |
1405 | DMA_SUCCESS) { | 1404 | DMA_SUCCESS) { |
1406 | /* Handle incomplete DMA receive */ | 1405 | /* Handle incomplete DMA receive */ |
1407 | struct tty_struct *tty = port->state->port.tty; | ||
1408 | struct dma_chan *chan = s->chan_rx; | 1406 | struct dma_chan *chan = s->chan_rx; |
1409 | struct shdma_desc *sh_desc = container_of(desc, | 1407 | struct shdma_desc *sh_desc = container_of(desc, |
1410 | struct shdma_desc, async_tx); | 1408 | struct shdma_desc, async_tx); |
@@ -1416,11 +1414,11 @@ static void work_fn_rx(struct work_struct *work) | |||
1416 | sh_desc->partial, sh_desc->cookie); | 1414 | sh_desc->partial, sh_desc->cookie); |
1417 | 1415 | ||
1418 | spin_lock_irqsave(&port->lock, flags); | 1416 | spin_lock_irqsave(&port->lock, flags); |
1419 | count = sci_dma_rx_push(s, tty, sh_desc->partial); | 1417 | count = sci_dma_rx_push(s, sh_desc->partial); |
1420 | spin_unlock_irqrestore(&port->lock, flags); | 1418 | spin_unlock_irqrestore(&port->lock, flags); |
1421 | 1419 | ||
1422 | if (count) | 1420 | if (count) |
1423 | tty_flip_buffer_push(tty); | 1421 | tty_flip_buffer_push(&port->state->port); |
1424 | 1422 | ||
1425 | sci_submit_rx(s); | 1423 | sci_submit_rx(s); |
1426 | 1424 | ||
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 5da5cb962769..6bbfe9934a4d 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -75,6 +75,20 @@ static struct sirfsoc_uart_port sirfsoc_uart_ports[SIRFSOC_UART_NR] = { | |||
75 | .line = 2, | 75 | .line = 2, |
76 | }, | 76 | }, |
77 | }, | 77 | }, |
78 | [3] = { | ||
79 | .port = { | ||
80 | .iotype = UPIO_MEM, | ||
81 | .flags = UPF_BOOT_AUTOCONF, | ||
82 | .line = 3, | ||
83 | }, | ||
84 | }, | ||
85 | [4] = { | ||
86 | .port = { | ||
87 | .iotype = UPIO_MEM, | ||
88 | .flags = UPF_BOOT_AUTOCONF, | ||
89 | .line = 4, | ||
90 | }, | ||
91 | }, | ||
78 | }; | 92 | }; |
79 | 93 | ||
80 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) | 94 | static inline struct sirfsoc_uart_port *to_sirfport(struct uart_port *port) |
@@ -192,11 +206,6 @@ static unsigned int | |||
192 | sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | 206 | sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) |
193 | { | 207 | { |
194 | unsigned int ch, rx_count = 0; | 208 | unsigned int ch, rx_count = 0; |
195 | struct tty_struct *tty; | ||
196 | |||
197 | tty = tty_port_tty_get(&port->state->port); | ||
198 | if (!tty) | ||
199 | return -ENODEV; | ||
200 | 209 | ||
201 | while (!(rd_regl(port, SIRFUART_RX_FIFO_STATUS) & | 210 | while (!(rd_regl(port, SIRFUART_RX_FIFO_STATUS) & |
202 | SIRFUART_FIFOEMPTY_MASK(port))) { | 211 | SIRFUART_FIFOEMPTY_MASK(port))) { |
@@ -210,8 +219,7 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | |||
210 | } | 219 | } |
211 | 220 | ||
212 | port->icount.rx += rx_count; | 221 | port->icount.rx += rx_count; |
213 | tty_flip_buffer_push(tty); | 222 | tty_flip_buffer_push(&port->state->port); |
214 | tty_kref_put(tty); | ||
215 | 223 | ||
216 | return rx_count; | 224 | return rx_count; |
217 | } | 225 | } |
@@ -245,6 +253,7 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | |||
245 | struct uart_port *port = &sirfport->port; | 253 | struct uart_port *port = &sirfport->port; |
246 | struct uart_state *state = port->state; | 254 | struct uart_state *state = port->state; |
247 | struct circ_buf *xmit = &port->state->xmit; | 255 | struct circ_buf *xmit = &port->state->xmit; |
256 | spin_lock(&port->lock); | ||
248 | intr_status = rd_regl(port, SIRFUART_INT_STATUS); | 257 | intr_status = rd_regl(port, SIRFUART_INT_STATUS); |
249 | wr_regl(port, SIRFUART_INT_STATUS, intr_status); | 258 | wr_regl(port, SIRFUART_INT_STATUS, intr_status); |
250 | intr_status &= rd_regl(port, SIRFUART_INT_EN); | 259 | intr_status &= rd_regl(port, SIRFUART_INT_EN); |
@@ -254,6 +263,7 @@ static irqreturn_t sirfsoc_uart_isr(int irq, void *dev_id) | |||
254 | goto recv_char; | 263 | goto recv_char; |
255 | uart_insert_char(port, intr_status, | 264 | uart_insert_char(port, intr_status, |
256 | SIRFUART_RX_OFLOW, 0, TTY_BREAK); | 265 | SIRFUART_RX_OFLOW, 0, TTY_BREAK); |
266 | spin_unlock(&port->lock); | ||
257 | return IRQ_HANDLED; | 267 | return IRQ_HANDLED; |
258 | } | 268 | } |
259 | if (intr_status & SIRFUART_RX_OFLOW) | 269 | if (intr_status & SIRFUART_RX_OFLOW) |
@@ -286,6 +296,7 @@ recv_char: | |||
286 | sirfsoc_uart_pio_rx_chars(port, SIRFSOC_UART_IO_RX_MAX_CNT); | 296 | sirfsoc_uart_pio_rx_chars(port, SIRFSOC_UART_IO_RX_MAX_CNT); |
287 | if (intr_status & SIRFUART_TX_INT_EN) { | 297 | if (intr_status & SIRFUART_TX_INT_EN) { |
288 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | 298 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { |
299 | spin_unlock(&port->lock); | ||
289 | return IRQ_HANDLED; | 300 | return IRQ_HANDLED; |
290 | } else { | 301 | } else { |
291 | sirfsoc_uart_pio_tx_chars(sirfport, | 302 | sirfsoc_uart_pio_tx_chars(sirfport, |
@@ -296,6 +307,7 @@ recv_char: | |||
296 | sirfsoc_uart_stop_tx(port); | 307 | sirfsoc_uart_stop_tx(port); |
297 | } | 308 | } |
298 | } | 309 | } |
310 | spin_unlock(&port->lock); | ||
299 | return IRQ_HANDLED; | 311 | return IRQ_HANDLED; |
300 | } | 312 | } |
301 | 313 | ||
@@ -345,7 +357,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
345 | struct ktermios *old) | 357 | struct ktermios *old) |
346 | { | 358 | { |
347 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 359 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
348 | unsigned long ioclk_rate; | ||
349 | unsigned long config_reg = 0; | 360 | unsigned long config_reg = 0; |
350 | unsigned long baud_rate; | 361 | unsigned long baud_rate; |
351 | unsigned long setted_baud; | 362 | unsigned long setted_baud; |
@@ -357,7 +368,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
357 | int threshold_div; | 368 | int threshold_div; |
358 | int temp; | 369 | int temp; |
359 | 370 | ||
360 | ioclk_rate = 150000000; | ||
361 | switch (termios->c_cflag & CSIZE) { | 371 | switch (termios->c_cflag & CSIZE) { |
362 | default: | 372 | default: |
363 | case CS8: | 373 | case CS8: |
@@ -413,14 +423,17 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
413 | sirfsoc_uart_disable_ms(port); | 423 | sirfsoc_uart_disable_ms(port); |
414 | } | 424 | } |
415 | 425 | ||
416 | /* common rate: fast calculation */ | 426 | if (port->uartclk == 150000000) { |
417 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) | 427 | /* common rate: fast calculation */ |
418 | if (baud_rate == baudrate_to_regv[ic].baud_rate) | 428 | for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) |
419 | clk_div_reg = baudrate_to_regv[ic].reg_val; | 429 | if (baud_rate == baudrate_to_regv[ic].baud_rate) |
430 | clk_div_reg = baudrate_to_regv[ic].reg_val; | ||
431 | } | ||
432 | |||
420 | setted_baud = baud_rate; | 433 | setted_baud = baud_rate; |
421 | /* arbitary rate setting */ | 434 | /* arbitary rate setting */ |
422 | if (unlikely(clk_div_reg == 0)) | 435 | if (unlikely(clk_div_reg == 0)) |
423 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate, | 436 | clk_div_reg = sirfsoc_calc_sample_div(baud_rate, port->uartclk, |
424 | &setted_baud); | 437 | &setted_baud); |
425 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); | 438 | wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); |
426 | 439 | ||
@@ -679,6 +692,14 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
679 | goto err; | 692 | goto err; |
680 | } | 693 | } |
681 | 694 | ||
695 | sirfport->clk = clk_get(&pdev->dev, NULL); | ||
696 | if (IS_ERR(sirfport->clk)) { | ||
697 | ret = PTR_ERR(sirfport->clk); | ||
698 | goto clk_err; | ||
699 | } | ||
700 | clk_prepare_enable(sirfport->clk); | ||
701 | port->uartclk = clk_get_rate(sirfport->clk); | ||
702 | |||
682 | port->ops = &sirfsoc_uart_ops; | 703 | port->ops = &sirfsoc_uart_ops; |
683 | spin_lock_init(&port->lock); | 704 | spin_lock_init(&port->lock); |
684 | 705 | ||
@@ -692,6 +713,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
692 | return 0; | 713 | return 0; |
693 | 714 | ||
694 | port_err: | 715 | port_err: |
716 | clk_disable_unprepare(sirfport->clk); | ||
717 | clk_put(sirfport->clk); | ||
718 | clk_err: | ||
695 | platform_set_drvdata(pdev, NULL); | 719 | platform_set_drvdata(pdev, NULL); |
696 | if (sirfport->hw_flow_ctrl) | 720 | if (sirfport->hw_flow_ctrl) |
697 | pinctrl_put(sirfport->p); | 721 | pinctrl_put(sirfport->p); |
@@ -706,6 +730,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) | |||
706 | platform_set_drvdata(pdev, NULL); | 730 | platform_set_drvdata(pdev, NULL); |
707 | if (sirfport->hw_flow_ctrl) | 731 | if (sirfport->hw_flow_ctrl) |
708 | pinctrl_put(sirfport->p); | 732 | pinctrl_put(sirfport->p); |
733 | clk_disable_unprepare(sirfport->clk); | ||
734 | clk_put(sirfport->clk); | ||
709 | uart_remove_one_port(&sirfsoc_uart_drv, port); | 735 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
710 | return 0; | 736 | return 0; |
711 | } | 737 | } |
@@ -729,6 +755,7 @@ static int sirfsoc_uart_resume(struct platform_device *pdev) | |||
729 | 755 | ||
730 | static struct of_device_id sirfsoc_uart_ids[] = { | 756 | static struct of_device_id sirfsoc_uart_ids[] = { |
731 | { .compatible = "sirf,prima2-uart", }, | 757 | { .compatible = "sirf,prima2-uart", }, |
758 | { .compatible = "sirf,marco-uart", }, | ||
732 | {} | 759 | {} |
733 | }; | 760 | }; |
734 | MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); | 761 | MODULE_DEVICE_TABLE(of, sirfsoc_serial_of_match); |
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index 6e207fdc2fed..85328ba0c4e3 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -139,7 +139,7 @@ | |||
139 | #define SIRFSOC_UART_MINOR 0 | 139 | #define SIRFSOC_UART_MINOR 0 |
140 | #define SIRFUART_PORT_NAME "sirfsoc-uart" | 140 | #define SIRFUART_PORT_NAME "sirfsoc-uart" |
141 | #define SIRFUART_MAP_SIZE 0x200 | 141 | #define SIRFUART_MAP_SIZE 0x200 |
142 | #define SIRFSOC_UART_NR 3 | 142 | #define SIRFSOC_UART_NR 5 |
143 | #define SIRFSOC_PORT_TYPE 0xa5 | 143 | #define SIRFSOC_PORT_TYPE 0xa5 |
144 | 144 | ||
145 | /* Baud Rate Calculation */ | 145 | /* Baud Rate Calculation */ |
@@ -163,6 +163,7 @@ struct sirfsoc_uart_port { | |||
163 | 163 | ||
164 | struct uart_port port; | 164 | struct uart_port port; |
165 | struct pinctrl *p; | 165 | struct pinctrl *p; |
166 | struct clk *clk; | ||
166 | }; | 167 | }; |
167 | 168 | ||
168 | /* Hardware Flow Control */ | 169 | /* Hardware Flow Control */ |
diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c index 1c6de9f58699..f51ffdc696fd 100644 --- a/drivers/tty/serial/sn_console.c +++ b/drivers/tty/serial/sn_console.c | |||
@@ -457,8 +457,8 @@ static int sn_debug_printf(const char *fmt, ...) | |||
457 | static void | 457 | static void |
458 | sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | 458 | sn_receive_chars(struct sn_cons_port *port, unsigned long flags) |
459 | { | 459 | { |
460 | struct tty_port *tport = NULL; | ||
460 | int ch; | 461 | int ch; |
461 | struct tty_struct *tty; | ||
462 | 462 | ||
463 | if (!port) { | 463 | if (!port) { |
464 | printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n"); | 464 | printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n"); |
@@ -472,11 +472,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
472 | 472 | ||
473 | if (port->sc_port.state) { | 473 | if (port->sc_port.state) { |
474 | /* The serial_core stuffs are initialized, use them */ | 474 | /* The serial_core stuffs are initialized, use them */ |
475 | tty = port->sc_port.state->port.tty; | 475 | tport = &port->sc_port.state->port; |
476 | } | ||
477 | else { | ||
478 | /* Not registered yet - can't pass to tty layer. */ | ||
479 | tty = NULL; | ||
480 | } | 476 | } |
481 | 477 | ||
482 | while (port->sc_ops->sal_input_pending()) { | 478 | while (port->sc_ops->sal_input_pending()) { |
@@ -516,15 +512,15 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
516 | #endif /* CONFIG_MAGIC_SYSRQ */ | 512 | #endif /* CONFIG_MAGIC_SYSRQ */ |
517 | 513 | ||
518 | /* record the character to pass up to the tty layer */ | 514 | /* record the character to pass up to the tty layer */ |
519 | if (tty) { | 515 | if (tport) { |
520 | if(tty_insert_flip_char(tty, ch, TTY_NORMAL) == 0) | 516 | if (tty_insert_flip_char(tport, ch, TTY_NORMAL) == 0) |
521 | break; | 517 | break; |
522 | } | 518 | } |
523 | port->sc_port.icount.rx++; | 519 | port->sc_port.icount.rx++; |
524 | } | 520 | } |
525 | 521 | ||
526 | if (tty) | 522 | if (tport) |
527 | tty_flip_buffer_push(tty); | 523 | tty_flip_buffer_push(tport); |
528 | } | 524 | } |
529 | 525 | ||
530 | /** | 526 | /** |
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index b9bf9c53f7fd..ba60708053e0 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c | |||
@@ -72,7 +72,7 @@ static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit) | |||
72 | } | 72 | } |
73 | } | 73 | } |
74 | 74 | ||
75 | static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | 75 | static int receive_chars_getchar(struct uart_port *port) |
76 | { | 76 | { |
77 | int saw_console_brk = 0; | 77 | int saw_console_brk = 0; |
78 | int limit = 10000; | 78 | int limit = 10000; |
@@ -99,7 +99,7 @@ static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | |||
99 | uart_handle_dcd_change(port, 1); | 99 | uart_handle_dcd_change(port, 1); |
100 | } | 100 | } |
101 | 101 | ||
102 | if (tty == NULL) { | 102 | if (port->state == NULL) { |
103 | uart_handle_sysrq_char(port, c); | 103 | uart_handle_sysrq_char(port, c); |
104 | continue; | 104 | continue; |
105 | } | 105 | } |
@@ -109,13 +109,13 @@ static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty) | |||
109 | if (uart_handle_sysrq_char(port, c)) | 109 | if (uart_handle_sysrq_char(port, c)) |
110 | continue; | 110 | continue; |
111 | 111 | ||
112 | tty_insert_flip_char(tty, c, TTY_NORMAL); | 112 | tty_insert_flip_char(&port->state->port, c, TTY_NORMAL); |
113 | } | 113 | } |
114 | 114 | ||
115 | return saw_console_brk; | 115 | return saw_console_brk; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | 118 | static int receive_chars_read(struct uart_port *port) |
119 | { | 119 | { |
120 | int saw_console_brk = 0; | 120 | int saw_console_brk = 0; |
121 | int limit = 10000; | 121 | int limit = 10000; |
@@ -152,12 +152,13 @@ static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | |||
152 | for (i = 0; i < bytes_read; i++) | 152 | for (i = 0; i < bytes_read; i++) |
153 | uart_handle_sysrq_char(port, con_read_page[i]); | 153 | uart_handle_sysrq_char(port, con_read_page[i]); |
154 | 154 | ||
155 | if (tty == NULL) | 155 | if (port->state == NULL) |
156 | continue; | 156 | continue; |
157 | 157 | ||
158 | port->icount.rx += bytes_read; | 158 | port->icount.rx += bytes_read; |
159 | 159 | ||
160 | tty_insert_flip_string(tty, con_read_page, bytes_read); | 160 | tty_insert_flip_string(&port->state->port, con_read_page, |
161 | bytes_read); | ||
161 | } | 162 | } |
162 | 163 | ||
163 | return saw_console_brk; | 164 | return saw_console_brk; |
@@ -165,7 +166,7 @@ static int receive_chars_read(struct uart_port *port, struct tty_struct *tty) | |||
165 | 166 | ||
166 | struct sunhv_ops { | 167 | struct sunhv_ops { |
167 | void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit); | 168 | void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit); |
168 | int (*receive_chars)(struct uart_port *port, struct tty_struct *tty); | 169 | int (*receive_chars)(struct uart_port *port); |
169 | }; | 170 | }; |
170 | 171 | ||
171 | static struct sunhv_ops bychar_ops = { | 172 | static struct sunhv_ops bychar_ops = { |
@@ -180,17 +181,17 @@ static struct sunhv_ops bywrite_ops = { | |||
180 | 181 | ||
181 | static struct sunhv_ops *sunhv_ops = &bychar_ops; | 182 | static struct sunhv_ops *sunhv_ops = &bychar_ops; |
182 | 183 | ||
183 | static struct tty_struct *receive_chars(struct uart_port *port) | 184 | static struct tty_port *receive_chars(struct uart_port *port) |
184 | { | 185 | { |
185 | struct tty_struct *tty = NULL; | 186 | struct tty_port *tport = NULL; |
186 | 187 | ||
187 | if (port->state != NULL) /* Unopened serial console */ | 188 | if (port->state != NULL) /* Unopened serial console */ |
188 | tty = port->state->port.tty; | 189 | tport = &port->state->port; |
189 | 190 | ||
190 | if (sunhv_ops->receive_chars(port, tty)) | 191 | if (sunhv_ops->receive_chars(port)) |
191 | sun_do_break(); | 192 | sun_do_break(); |
192 | 193 | ||
193 | return tty; | 194 | return tport; |
194 | } | 195 | } |
195 | 196 | ||
196 | static void transmit_chars(struct uart_port *port) | 197 | static void transmit_chars(struct uart_port *port) |
@@ -213,16 +214,16 @@ static void transmit_chars(struct uart_port *port) | |||
213 | static irqreturn_t sunhv_interrupt(int irq, void *dev_id) | 214 | static irqreturn_t sunhv_interrupt(int irq, void *dev_id) |
214 | { | 215 | { |
215 | struct uart_port *port = dev_id; | 216 | struct uart_port *port = dev_id; |
216 | struct tty_struct *tty; | 217 | struct tty_port *tport; |
217 | unsigned long flags; | 218 | unsigned long flags; |
218 | 219 | ||
219 | spin_lock_irqsave(&port->lock, flags); | 220 | spin_lock_irqsave(&port->lock, flags); |
220 | tty = receive_chars(port); | 221 | tport = receive_chars(port); |
221 | transmit_chars(port); | 222 | transmit_chars(port); |
222 | spin_unlock_irqrestore(&port->lock, flags); | 223 | spin_unlock_irqrestore(&port->lock, flags); |
223 | 224 | ||
224 | if (tty) | 225 | if (tport) |
225 | tty_flip_buffer_push(tty); | 226 | tty_flip_buffer_push(tport); |
226 | 227 | ||
227 | return IRQ_HANDLED; | 228 | return IRQ_HANDLED; |
228 | } | 229 | } |
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index bd8b3b634103..8de2213664e0 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c | |||
@@ -107,11 +107,11 @@ static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up) | |||
107 | udelay(1); | 107 | udelay(1); |
108 | } | 108 | } |
109 | 109 | ||
110 | static struct tty_struct * | 110 | static struct tty_port * |
111 | receive_chars(struct uart_sunsab_port *up, | 111 | receive_chars(struct uart_sunsab_port *up, |
112 | union sab82532_irq_status *stat) | 112 | union sab82532_irq_status *stat) |
113 | { | 113 | { |
114 | struct tty_struct *tty = NULL; | 114 | struct tty_port *port = NULL; |
115 | unsigned char buf[32]; | 115 | unsigned char buf[32]; |
116 | int saw_console_brk = 0; | 116 | int saw_console_brk = 0; |
117 | int free_fifo = 0; | 117 | int free_fifo = 0; |
@@ -119,7 +119,7 @@ receive_chars(struct uart_sunsab_port *up, | |||
119 | int i; | 119 | int i; |
120 | 120 | ||
121 | if (up->port.state != NULL) /* Unopened serial console */ | 121 | if (up->port.state != NULL) /* Unopened serial console */ |
122 | tty = up->port.state->port.tty; | 122 | port = &up->port.state->port; |
123 | 123 | ||
124 | /* Read number of BYTES (Character + Status) available. */ | 124 | /* Read number of BYTES (Character + Status) available. */ |
125 | if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { | 125 | if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { |
@@ -136,7 +136,7 @@ receive_chars(struct uart_sunsab_port *up, | |||
136 | if (stat->sreg.isr0 & SAB82532_ISR0_TIME) { | 136 | if (stat->sreg.isr0 & SAB82532_ISR0_TIME) { |
137 | sunsab_cec_wait(up); | 137 | sunsab_cec_wait(up); |
138 | writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr); | 138 | writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr); |
139 | return tty; | 139 | return port; |
140 | } | 140 | } |
141 | 141 | ||
142 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) | 142 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) |
@@ -160,11 +160,6 @@ receive_chars(struct uart_sunsab_port *up, | |||
160 | for (i = 0; i < count; i++) { | 160 | for (i = 0; i < count; i++) { |
161 | unsigned char ch = buf[i], flag; | 161 | unsigned char ch = buf[i], flag; |
162 | 162 | ||
163 | if (tty == NULL) { | ||
164 | uart_handle_sysrq_char(&up->port, ch); | ||
165 | continue; | ||
166 | } | ||
167 | |||
168 | flag = TTY_NORMAL; | 163 | flag = TTY_NORMAL; |
169 | up->port.icount.rx++; | 164 | up->port.icount.rx++; |
170 | 165 | ||
@@ -213,15 +208,15 @@ receive_chars(struct uart_sunsab_port *up, | |||
213 | 208 | ||
214 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && | 209 | if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && |
215 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) | 210 | (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) |
216 | tty_insert_flip_char(tty, ch, flag); | 211 | tty_insert_flip_char(port, ch, flag); |
217 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) | 212 | if (stat->sreg.isr0 & SAB82532_ISR0_RFO) |
218 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 213 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
219 | } | 214 | } |
220 | 215 | ||
221 | if (saw_console_brk) | 216 | if (saw_console_brk) |
222 | sun_do_break(); | 217 | sun_do_break(); |
223 | 218 | ||
224 | return tty; | 219 | return port; |
225 | } | 220 | } |
226 | 221 | ||
227 | static void sunsab_stop_tx(struct uart_port *); | 222 | static void sunsab_stop_tx(struct uart_port *); |
@@ -304,7 +299,7 @@ static void check_status(struct uart_sunsab_port *up, | |||
304 | static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | 299 | static irqreturn_t sunsab_interrupt(int irq, void *dev_id) |
305 | { | 300 | { |
306 | struct uart_sunsab_port *up = dev_id; | 301 | struct uart_sunsab_port *up = dev_id; |
307 | struct tty_struct *tty; | 302 | struct tty_port *port = NULL; |
308 | union sab82532_irq_status status; | 303 | union sab82532_irq_status status; |
309 | unsigned long flags; | 304 | unsigned long flags; |
310 | unsigned char gis; | 305 | unsigned char gis; |
@@ -318,12 +313,11 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | |||
318 | if (gis & 2) | 313 | if (gis & 2) |
319 | status.sreg.isr1 = readb(&up->regs->r.isr1); | 314 | status.sreg.isr1 = readb(&up->regs->r.isr1); |
320 | 315 | ||
321 | tty = NULL; | ||
322 | if (status.stat) { | 316 | if (status.stat) { |
323 | if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | | 317 | if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | |
324 | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || | 318 | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || |
325 | (status.sreg.isr1 & SAB82532_ISR1_BRK)) | 319 | (status.sreg.isr1 & SAB82532_ISR1_BRK)) |
326 | tty = receive_chars(up, &status); | 320 | port = receive_chars(up, &status); |
327 | if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || | 321 | if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || |
328 | (status.sreg.isr1 & SAB82532_ISR1_CSC)) | 322 | (status.sreg.isr1 & SAB82532_ISR1_CSC)) |
329 | check_status(up, &status); | 323 | check_status(up, &status); |
@@ -333,8 +327,8 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) | |||
333 | 327 | ||
334 | spin_unlock_irqrestore(&up->port.lock, flags); | 328 | spin_unlock_irqrestore(&up->port.lock, flags); |
335 | 329 | ||
336 | if (tty) | 330 | if (port) |
337 | tty_flip_buffer_push(tty); | 331 | tty_flip_buffer_push(port); |
338 | 332 | ||
339 | return IRQ_HANDLED; | 333 | return IRQ_HANDLED; |
340 | } | 334 | } |
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 220da3f9724f..e343d6670854 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c | |||
@@ -315,10 +315,10 @@ static void sunsu_enable_ms(struct uart_port *port) | |||
315 | spin_unlock_irqrestore(&up->port.lock, flags); | 315 | spin_unlock_irqrestore(&up->port.lock, flags); |
316 | } | 316 | } |
317 | 317 | ||
318 | static struct tty_struct * | 318 | static void |
319 | receive_chars(struct uart_sunsu_port *up, unsigned char *status) | 319 | receive_chars(struct uart_sunsu_port *up, unsigned char *status) |
320 | { | 320 | { |
321 | struct tty_struct *tty = up->port.state->port.tty; | 321 | struct tty_port *port = &up->port.state->port; |
322 | unsigned char ch, flag; | 322 | unsigned char ch, flag; |
323 | int max_count = 256; | 323 | int max_count = 256; |
324 | int saw_console_brk = 0; | 324 | int saw_console_brk = 0; |
@@ -376,22 +376,20 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status) | |||
376 | if (uart_handle_sysrq_char(&up->port, ch)) | 376 | if (uart_handle_sysrq_char(&up->port, ch)) |
377 | goto ignore_char; | 377 | goto ignore_char; |
378 | if ((*status & up->port.ignore_status_mask) == 0) | 378 | if ((*status & up->port.ignore_status_mask) == 0) |
379 | tty_insert_flip_char(tty, ch, flag); | 379 | tty_insert_flip_char(port, ch, flag); |
380 | if (*status & UART_LSR_OE) | 380 | if (*status & UART_LSR_OE) |
381 | /* | 381 | /* |
382 | * Overrun is special, since it's reported | 382 | * Overrun is special, since it's reported |
383 | * immediately, and doesn't affect the current | 383 | * immediately, and doesn't affect the current |
384 | * character. | 384 | * character. |
385 | */ | 385 | */ |
386 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 386 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
387 | ignore_char: | 387 | ignore_char: |
388 | *status = serial_inp(up, UART_LSR); | 388 | *status = serial_inp(up, UART_LSR); |
389 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 389 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
390 | 390 | ||
391 | if (saw_console_brk) | 391 | if (saw_console_brk) |
392 | sun_do_break(); | 392 | sun_do_break(); |
393 | |||
394 | return tty; | ||
395 | } | 393 | } |
396 | 394 | ||
397 | static void transmit_chars(struct uart_sunsu_port *up) | 395 | static void transmit_chars(struct uart_sunsu_port *up) |
@@ -460,20 +458,16 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id) | |||
460 | spin_lock_irqsave(&up->port.lock, flags); | 458 | spin_lock_irqsave(&up->port.lock, flags); |
461 | 459 | ||
462 | do { | 460 | do { |
463 | struct tty_struct *tty; | ||
464 | |||
465 | status = serial_inp(up, UART_LSR); | 461 | status = serial_inp(up, UART_LSR); |
466 | tty = NULL; | ||
467 | if (status & UART_LSR_DR) | 462 | if (status & UART_LSR_DR) |
468 | tty = receive_chars(up, &status); | 463 | receive_chars(up, &status); |
469 | check_modem_status(up); | 464 | check_modem_status(up); |
470 | if (status & UART_LSR_THRE) | 465 | if (status & UART_LSR_THRE) |
471 | transmit_chars(up); | 466 | transmit_chars(up); |
472 | 467 | ||
473 | spin_unlock_irqrestore(&up->port.lock, flags); | 468 | spin_unlock_irqrestore(&up->port.lock, flags); |
474 | 469 | ||
475 | if (tty) | 470 | tty_flip_buffer_push(&up->port.state->port); |
476 | tty_flip_buffer_push(tty); | ||
477 | 471 | ||
478 | spin_lock_irqsave(&up->port.lock, flags); | 472 | spin_lock_irqsave(&up->port.lock, flags); |
479 | 473 | ||
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index aef4fab957c3..27669ff3d446 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c | |||
@@ -323,17 +323,15 @@ static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up, | |||
323 | } | 323 | } |
324 | } | 324 | } |
325 | 325 | ||
326 | static struct tty_struct * | 326 | static struct tty_port * |
327 | sunzilog_receive_chars(struct uart_sunzilog_port *up, | 327 | sunzilog_receive_chars(struct uart_sunzilog_port *up, |
328 | struct zilog_channel __iomem *channel) | 328 | struct zilog_channel __iomem *channel) |
329 | { | 329 | { |
330 | struct tty_struct *tty; | 330 | struct tty_port *port = NULL; |
331 | unsigned char ch, r1, flag; | 331 | unsigned char ch, r1, flag; |
332 | 332 | ||
333 | tty = NULL; | 333 | if (up->port.state != NULL) /* Unopened serial console */ |
334 | if (up->port.state != NULL && /* Unopened serial console */ | 334 | port = &up->port.state->port; |
335 | up->port.state->port.tty != NULL) /* Keyboard || mouse */ | ||
336 | tty = up->port.state->port.tty; | ||
337 | 335 | ||
338 | for (;;) { | 336 | for (;;) { |
339 | 337 | ||
@@ -366,11 +364,6 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
366 | continue; | 364 | continue; |
367 | } | 365 | } |
368 | 366 | ||
369 | if (tty == NULL) { | ||
370 | uart_handle_sysrq_char(&up->port, ch); | ||
371 | continue; | ||
372 | } | ||
373 | |||
374 | /* A real serial line, record the character and status. */ | 367 | /* A real serial line, record the character and status. */ |
375 | flag = TTY_NORMAL; | 368 | flag = TTY_NORMAL; |
376 | up->port.icount.rx++; | 369 | up->port.icount.rx++; |
@@ -400,13 +393,13 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up, | |||
400 | 393 | ||
401 | if (up->port.ignore_status_mask == 0xff || | 394 | if (up->port.ignore_status_mask == 0xff || |
402 | (r1 & up->port.ignore_status_mask) == 0) { | 395 | (r1 & up->port.ignore_status_mask) == 0) { |
403 | tty_insert_flip_char(tty, ch, flag); | 396 | tty_insert_flip_char(port, ch, flag); |
404 | } | 397 | } |
405 | if (r1 & Rx_OVR) | 398 | if (r1 & Rx_OVR) |
406 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 399 | tty_insert_flip_char(port, 0, TTY_OVERRUN); |
407 | } | 400 | } |
408 | 401 | ||
409 | return tty; | 402 | return port; |
410 | } | 403 | } |
411 | 404 | ||
412 | static void sunzilog_status_handle(struct uart_sunzilog_port *up, | 405 | static void sunzilog_status_handle(struct uart_sunzilog_port *up, |
@@ -539,21 +532,21 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
539 | while (up) { | 532 | while (up) { |
540 | struct zilog_channel __iomem *channel | 533 | struct zilog_channel __iomem *channel |
541 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | 534 | = ZILOG_CHANNEL_FROM_PORT(&up->port); |
542 | struct tty_struct *tty; | 535 | struct tty_port *port; |
543 | unsigned char r3; | 536 | unsigned char r3; |
544 | 537 | ||
545 | spin_lock(&up->port.lock); | 538 | spin_lock(&up->port.lock); |
546 | r3 = read_zsreg(channel, R3); | 539 | r3 = read_zsreg(channel, R3); |
547 | 540 | ||
548 | /* Channel A */ | 541 | /* Channel A */ |
549 | tty = NULL; | 542 | port = NULL; |
550 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 543 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
551 | writeb(RES_H_IUS, &channel->control); | 544 | writeb(RES_H_IUS, &channel->control); |
552 | ZSDELAY(); | 545 | ZSDELAY(); |
553 | ZS_WSYNC(channel); | 546 | ZS_WSYNC(channel); |
554 | 547 | ||
555 | if (r3 & CHARxIP) | 548 | if (r3 & CHARxIP) |
556 | tty = sunzilog_receive_chars(up, channel); | 549 | port = sunzilog_receive_chars(up, channel); |
557 | if (r3 & CHAEXT) | 550 | if (r3 & CHAEXT) |
558 | sunzilog_status_handle(up, channel); | 551 | sunzilog_status_handle(up, channel); |
559 | if (r3 & CHATxIP) | 552 | if (r3 & CHATxIP) |
@@ -561,22 +554,22 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
561 | } | 554 | } |
562 | spin_unlock(&up->port.lock); | 555 | spin_unlock(&up->port.lock); |
563 | 556 | ||
564 | if (tty) | 557 | if (port) |
565 | tty_flip_buffer_push(tty); | 558 | tty_flip_buffer_push(port); |
566 | 559 | ||
567 | /* Channel B */ | 560 | /* Channel B */ |
568 | up = up->next; | 561 | up = up->next; |
569 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | 562 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); |
570 | 563 | ||
571 | spin_lock(&up->port.lock); | 564 | spin_lock(&up->port.lock); |
572 | tty = NULL; | 565 | port = NULL; |
573 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 566 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
574 | writeb(RES_H_IUS, &channel->control); | 567 | writeb(RES_H_IUS, &channel->control); |
575 | ZSDELAY(); | 568 | ZSDELAY(); |
576 | ZS_WSYNC(channel); | 569 | ZS_WSYNC(channel); |
577 | 570 | ||
578 | if (r3 & CHBRxIP) | 571 | if (r3 & CHBRxIP) |
579 | tty = sunzilog_receive_chars(up, channel); | 572 | port = sunzilog_receive_chars(up, channel); |
580 | if (r3 & CHBEXT) | 573 | if (r3 & CHBEXT) |
581 | sunzilog_status_handle(up, channel); | 574 | sunzilog_status_handle(up, channel); |
582 | if (r3 & CHBTxIP) | 575 | if (r3 & CHBTxIP) |
@@ -584,8 +577,8 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id) | |||
584 | } | 577 | } |
585 | spin_unlock(&up->port.lock); | 578 | spin_unlock(&up->port.lock); |
586 | 579 | ||
587 | if (tty) | 580 | if (port) |
588 | tty_flip_buffer_push(tty); | 581 | tty_flip_buffer_push(port); |
589 | 582 | ||
590 | up = up->next; | 583 | up = up->next; |
591 | } | 584 | } |
diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 5be0d68feceb..6818410a2bea 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c | |||
@@ -91,16 +91,16 @@ static void timbuart_flush_buffer(struct uart_port *port) | |||
91 | 91 | ||
92 | static void timbuart_rx_chars(struct uart_port *port) | 92 | static void timbuart_rx_chars(struct uart_port *port) |
93 | { | 93 | { |
94 | struct tty_struct *tty = port->state->port.tty; | 94 | struct tty_port *tport = &port->state->port; |
95 | 95 | ||
96 | while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { | 96 | while (ioread32(port->membase + TIMBUART_ISR) & RXDP) { |
97 | u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); | 97 | u8 ch = ioread8(port->membase + TIMBUART_RXFIFO); |
98 | port->icount.rx++; | 98 | port->icount.rx++; |
99 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | 99 | tty_insert_flip_char(tport, ch, TTY_NORMAL); |
100 | } | 100 | } |
101 | 101 | ||
102 | spin_unlock(&port->lock); | 102 | spin_unlock(&port->lock); |
103 | tty_flip_buffer_push(port->state->port.tty); | 103 | tty_flip_buffer_push(tport); |
104 | spin_lock(&port->lock); | 104 | spin_lock(&port->lock); |
105 | 105 | ||
106 | dev_dbg(port->dev, "%s - total read %d bytes\n", | 106 | dev_dbg(port->dev, "%s - total read %d bytes\n", |
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 89eee43c4e2d..5f90ef24d475 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <asm/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
25 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
@@ -34,7 +34,7 @@ | |||
34 | * Register definitions | 34 | * Register definitions |
35 | * | 35 | * |
36 | * For register details see datasheet: | 36 | * For register details see datasheet: |
37 | * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf | 37 | * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf |
38 | */ | 38 | */ |
39 | 39 | ||
40 | #define ULITE_RX 0x00 | 40 | #define ULITE_RX 0x00 |
@@ -57,6 +57,54 @@ | |||
57 | #define ULITE_CONTROL_RST_RX 0x02 | 57 | #define ULITE_CONTROL_RST_RX 0x02 |
58 | #define ULITE_CONTROL_IE 0x10 | 58 | #define ULITE_CONTROL_IE 0x10 |
59 | 59 | ||
60 | struct uartlite_reg_ops { | ||
61 | u32 (*in)(void __iomem *addr); | ||
62 | void (*out)(u32 val, void __iomem *addr); | ||
63 | }; | ||
64 | |||
65 | static u32 uartlite_inbe32(void __iomem *addr) | ||
66 | { | ||
67 | return ioread32be(addr); | ||
68 | } | ||
69 | |||
70 | static void uartlite_outbe32(u32 val, void __iomem *addr) | ||
71 | { | ||
72 | iowrite32be(val, addr); | ||
73 | } | ||
74 | |||
75 | static struct uartlite_reg_ops uartlite_be = { | ||
76 | .in = uartlite_inbe32, | ||
77 | .out = uartlite_outbe32, | ||
78 | }; | ||
79 | |||
80 | static u32 uartlite_inle32(void __iomem *addr) | ||
81 | { | ||
82 | return ioread32(addr); | ||
83 | } | ||
84 | |||
85 | static void uartlite_outle32(u32 val, void __iomem *addr) | ||
86 | { | ||
87 | iowrite32(val, addr); | ||
88 | } | ||
89 | |||
90 | static struct uartlite_reg_ops uartlite_le = { | ||
91 | .in = uartlite_inle32, | ||
92 | .out = uartlite_outle32, | ||
93 | }; | ||
94 | |||
95 | static inline u32 uart_in32(u32 offset, struct uart_port *port) | ||
96 | { | ||
97 | struct uartlite_reg_ops *reg_ops = port->private_data; | ||
98 | |||
99 | return reg_ops->in(port->membase + offset); | ||
100 | } | ||
101 | |||
102 | static inline void uart_out32(u32 val, u32 offset, struct uart_port *port) | ||
103 | { | ||
104 | struct uartlite_reg_ops *reg_ops = port->private_data; | ||
105 | |||
106 | reg_ops->out(val, port->membase + offset); | ||
107 | } | ||
60 | 108 | ||
61 | static struct uart_port ulite_ports[ULITE_NR_UARTS]; | 109 | static struct uart_port ulite_ports[ULITE_NR_UARTS]; |
62 | 110 | ||
@@ -66,7 +114,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS]; | |||
66 | 114 | ||
67 | static int ulite_receive(struct uart_port *port, int stat) | 115 | static int ulite_receive(struct uart_port *port, int stat) |
68 | { | 116 | { |
69 | struct tty_struct *tty = port->state->port.tty; | 117 | struct tty_port *tport = &port->state->port; |
70 | unsigned char ch = 0; | 118 | unsigned char ch = 0; |
71 | char flag = TTY_NORMAL; | 119 | char flag = TTY_NORMAL; |
72 | 120 | ||
@@ -77,7 +125,7 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
77 | /* stats */ | 125 | /* stats */ |
78 | if (stat & ULITE_STATUS_RXVALID) { | 126 | if (stat & ULITE_STATUS_RXVALID) { |
79 | port->icount.rx++; | 127 | port->icount.rx++; |
80 | ch = ioread32be(port->membase + ULITE_RX); | 128 | ch = uart_in32(ULITE_RX, port); |
81 | 129 | ||
82 | if (stat & ULITE_STATUS_PARITY) | 130 | if (stat & ULITE_STATUS_PARITY) |
83 | port->icount.parity++; | 131 | port->icount.parity++; |
@@ -103,13 +151,13 @@ static int ulite_receive(struct uart_port *port, int stat) | |||
103 | stat &= ~port->ignore_status_mask; | 151 | stat &= ~port->ignore_status_mask; |
104 | 152 | ||
105 | if (stat & ULITE_STATUS_RXVALID) | 153 | if (stat & ULITE_STATUS_RXVALID) |
106 | tty_insert_flip_char(tty, ch, flag); | 154 | tty_insert_flip_char(tport, ch, flag); |
107 | 155 | ||
108 | if (stat & ULITE_STATUS_FRAME) | 156 | if (stat & ULITE_STATUS_FRAME) |
109 | tty_insert_flip_char(tty, 0, TTY_FRAME); | 157 | tty_insert_flip_char(tport, 0, TTY_FRAME); |
110 | 158 | ||
111 | if (stat & ULITE_STATUS_OVERRUN) | 159 | if (stat & ULITE_STATUS_OVERRUN) |
112 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 160 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
113 | 161 | ||
114 | return 1; | 162 | return 1; |
115 | } | 163 | } |
@@ -122,7 +170,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
122 | return 0; | 170 | return 0; |
123 | 171 | ||
124 | if (port->x_char) { | 172 | if (port->x_char) { |
125 | iowrite32be(port->x_char, port->membase + ULITE_TX); | 173 | uart_out32(port->x_char, ULITE_TX, port); |
126 | port->x_char = 0; | 174 | port->x_char = 0; |
127 | port->icount.tx++; | 175 | port->icount.tx++; |
128 | return 1; | 176 | return 1; |
@@ -131,7 +179,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
131 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | 179 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) |
132 | return 0; | 180 | return 0; |
133 | 181 | ||
134 | iowrite32be(xmit->buf[xmit->tail], port->membase + ULITE_TX); | 182 | uart_out32(xmit->buf[xmit->tail], ULITE_TX, port); |
135 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); | 183 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); |
136 | port->icount.tx++; | 184 | port->icount.tx++; |
137 | 185 | ||
@@ -148,7 +196,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) | |||
148 | int busy, n = 0; | 196 | int busy, n = 0; |
149 | 197 | ||
150 | do { | 198 | do { |
151 | int stat = ioread32be(port->membase + ULITE_STATUS); | 199 | int stat = uart_in32(ULITE_STATUS, port); |
152 | busy = ulite_receive(port, stat); | 200 | busy = ulite_receive(port, stat); |
153 | busy |= ulite_transmit(port, stat); | 201 | busy |= ulite_transmit(port, stat); |
154 | n++; | 202 | n++; |
@@ -156,7 +204,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) | |||
156 | 204 | ||
157 | /* work done? */ | 205 | /* work done? */ |
158 | if (n > 1) { | 206 | if (n > 1) { |
159 | tty_flip_buffer_push(port->state->port.tty); | 207 | tty_flip_buffer_push(&port->state->port); |
160 | return IRQ_HANDLED; | 208 | return IRQ_HANDLED; |
161 | } else { | 209 | } else { |
162 | return IRQ_NONE; | 210 | return IRQ_NONE; |
@@ -169,7 +217,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port) | |||
169 | unsigned int ret; | 217 | unsigned int ret; |
170 | 218 | ||
171 | spin_lock_irqsave(&port->lock, flags); | 219 | spin_lock_irqsave(&port->lock, flags); |
172 | ret = ioread32be(port->membase + ULITE_STATUS); | 220 | ret = uart_in32(ULITE_STATUS, port); |
173 | spin_unlock_irqrestore(&port->lock, flags); | 221 | spin_unlock_irqrestore(&port->lock, flags); |
174 | 222 | ||
175 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; | 223 | return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; |
@@ -192,7 +240,7 @@ static void ulite_stop_tx(struct uart_port *port) | |||
192 | 240 | ||
193 | static void ulite_start_tx(struct uart_port *port) | 241 | static void ulite_start_tx(struct uart_port *port) |
194 | { | 242 | { |
195 | ulite_transmit(port, ioread32be(port->membase + ULITE_STATUS)); | 243 | ulite_transmit(port, uart_in32(ULITE_STATUS, port)); |
196 | } | 244 | } |
197 | 245 | ||
198 | static void ulite_stop_rx(struct uart_port *port) | 246 | static void ulite_stop_rx(struct uart_port *port) |
@@ -220,17 +268,17 @@ static int ulite_startup(struct uart_port *port) | |||
220 | if (ret) | 268 | if (ret) |
221 | return ret; | 269 | return ret; |
222 | 270 | ||
223 | iowrite32be(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, | 271 | uart_out32(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, |
224 | port->membase + ULITE_CONTROL); | 272 | ULITE_CONTROL, port); |
225 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 273 | uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port); |
226 | 274 | ||
227 | return 0; | 275 | return 0; |
228 | } | 276 | } |
229 | 277 | ||
230 | static void ulite_shutdown(struct uart_port *port) | 278 | static void ulite_shutdown(struct uart_port *port) |
231 | { | 279 | { |
232 | iowrite32be(0, port->membase + ULITE_CONTROL); | 280 | uart_out32(0, ULITE_CONTROL, port); |
233 | ioread32be(port->membase + ULITE_CONTROL); /* dummy */ | 281 | uart_in32(ULITE_CONTROL, port); /* dummy */ |
234 | free_irq(port->irq, port); | 282 | free_irq(port->irq, port); |
235 | } | 283 | } |
236 | 284 | ||
@@ -281,6 +329,8 @@ static void ulite_release_port(struct uart_port *port) | |||
281 | 329 | ||
282 | static int ulite_request_port(struct uart_port *port) | 330 | static int ulite_request_port(struct uart_port *port) |
283 | { | 331 | { |
332 | int ret; | ||
333 | |||
284 | pr_debug("ulite console: port=%p; port->mapbase=%llx\n", | 334 | pr_debug("ulite console: port=%p; port->mapbase=%llx\n", |
285 | port, (unsigned long long) port->mapbase); | 335 | port, (unsigned long long) port->mapbase); |
286 | 336 | ||
@@ -296,6 +346,14 @@ static int ulite_request_port(struct uart_port *port) | |||
296 | return -EBUSY; | 346 | return -EBUSY; |
297 | } | 347 | } |
298 | 348 | ||
349 | port->private_data = &uartlite_be; | ||
350 | ret = uart_in32(ULITE_CONTROL, port); | ||
351 | uart_out32(ULITE_CONTROL_RST_TX, ULITE_CONTROL, port); | ||
352 | ret = uart_in32(ULITE_STATUS, port); | ||
353 | /* Endianess detection */ | ||
354 | if ((ret & ULITE_STATUS_TXEMPTY) != ULITE_STATUS_TXEMPTY) | ||
355 | port->private_data = &uartlite_le; | ||
356 | |||
299 | return 0; | 357 | return 0; |
300 | } | 358 | } |
301 | 359 | ||
@@ -314,20 +372,19 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
314 | #ifdef CONFIG_CONSOLE_POLL | 372 | #ifdef CONFIG_CONSOLE_POLL |
315 | static int ulite_get_poll_char(struct uart_port *port) | 373 | static int ulite_get_poll_char(struct uart_port *port) |
316 | { | 374 | { |
317 | if (!(ioread32be(port->membase + ULITE_STATUS) | 375 | if (!(uart_in32(ULITE_STATUS, port) & ULITE_STATUS_RXVALID)) |
318 | & ULITE_STATUS_RXVALID)) | ||
319 | return NO_POLL_CHAR; | 376 | return NO_POLL_CHAR; |
320 | 377 | ||
321 | return ioread32be(port->membase + ULITE_RX); | 378 | return uart_in32(ULITE_RX, port); |
322 | } | 379 | } |
323 | 380 | ||
324 | static void ulite_put_poll_char(struct uart_port *port, unsigned char ch) | 381 | static void ulite_put_poll_char(struct uart_port *port, unsigned char ch) |
325 | { | 382 | { |
326 | while (ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_TXFULL) | 383 | while (uart_in32(ULITE_STATUS, port) & ULITE_STATUS_TXFULL) |
327 | cpu_relax(); | 384 | cpu_relax(); |
328 | 385 | ||
329 | /* write char to device */ | 386 | /* write char to device */ |
330 | iowrite32be(ch, port->membase + ULITE_TX); | 387 | uart_out32(ch, ULITE_TX, port); |
331 | } | 388 | } |
332 | #endif | 389 | #endif |
333 | 390 | ||
@@ -366,7 +423,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
366 | 423 | ||
367 | /* Spin waiting for TX fifo to have space available */ | 424 | /* Spin waiting for TX fifo to have space available */ |
368 | for (i = 0; i < 100000; i++) { | 425 | for (i = 0; i < 100000; i++) { |
369 | val = ioread32be(port->membase + ULITE_STATUS); | 426 | val = uart_in32(ULITE_STATUS, port); |
370 | if ((val & ULITE_STATUS_TXFULL) == 0) | 427 | if ((val & ULITE_STATUS_TXFULL) == 0) |
371 | break; | 428 | break; |
372 | cpu_relax(); | 429 | cpu_relax(); |
@@ -376,7 +433,7 @@ static void ulite_console_wait_tx(struct uart_port *port) | |||
376 | static void ulite_console_putchar(struct uart_port *port, int ch) | 433 | static void ulite_console_putchar(struct uart_port *port, int ch) |
377 | { | 434 | { |
378 | ulite_console_wait_tx(port); | 435 | ulite_console_wait_tx(port); |
379 | iowrite32be(ch, port->membase + ULITE_TX); | 436 | uart_out32(ch, ULITE_TX, port); |
380 | } | 437 | } |
381 | 438 | ||
382 | static void ulite_console_write(struct console *co, const char *s, | 439 | static void ulite_console_write(struct console *co, const char *s, |
@@ -393,8 +450,8 @@ static void ulite_console_write(struct console *co, const char *s, | |||
393 | spin_lock_irqsave(&port->lock, flags); | 450 | spin_lock_irqsave(&port->lock, flags); |
394 | 451 | ||
395 | /* save and disable interrupt */ | 452 | /* save and disable interrupt */ |
396 | ier = ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; | 453 | ier = uart_in32(ULITE_STATUS, port) & ULITE_STATUS_IE; |
397 | iowrite32be(0, port->membase + ULITE_CONTROL); | 454 | uart_out32(0, ULITE_CONTROL, port); |
398 | 455 | ||
399 | uart_console_write(port, s, count, ulite_console_putchar); | 456 | uart_console_write(port, s, count, ulite_console_putchar); |
400 | 457 | ||
@@ -402,7 +459,7 @@ static void ulite_console_write(struct console *co, const char *s, | |||
402 | 459 | ||
403 | /* restore interrupt state */ | 460 | /* restore interrupt state */ |
404 | if (ier) | 461 | if (ier) |
405 | iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); | 462 | uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port); |
406 | 463 | ||
407 | if (locked) | 464 | if (locked) |
408 | spin_unlock_irqrestore(&port->lock, flags); | 465 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -615,7 +672,7 @@ static struct platform_driver ulite_platform_driver = { | |||
615 | * Module setup/teardown | 672 | * Module setup/teardown |
616 | */ | 673 | */ |
617 | 674 | ||
618 | int __init ulite_init(void) | 675 | static int __init ulite_init(void) |
619 | { | 676 | { |
620 | int ret; | 677 | int ret; |
621 | 678 | ||
@@ -634,11 +691,11 @@ int __init ulite_init(void) | |||
634 | err_plat: | 691 | err_plat: |
635 | uart_unregister_driver(&ulite_uart_driver); | 692 | uart_unregister_driver(&ulite_uart_driver); |
636 | err_uart: | 693 | err_uart: |
637 | printk(KERN_ERR "registering uartlite driver failed: err=%i", ret); | 694 | pr_err("registering uartlite driver failed: err=%i", ret); |
638 | return ret; | 695 | return ret; |
639 | } | 696 | } |
640 | 697 | ||
641 | void __exit ulite_exit(void) | 698 | static void __exit ulite_exit(void) |
642 | { | 699 | { |
643 | platform_driver_unregister(&ulite_platform_driver); | 700 | platform_driver_unregister(&ulite_platform_driver); |
644 | uart_unregister_driver(&ulite_uart_driver); | 701 | uart_unregister_driver(&ulite_uart_driver); |
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index f99b0c965f85..7355303dad99 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c | |||
@@ -469,7 +469,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
469 | int i; | 469 | int i; |
470 | unsigned char ch, *cp; | 470 | unsigned char ch, *cp; |
471 | struct uart_port *port = &qe_port->port; | 471 | struct uart_port *port = &qe_port->port; |
472 | struct tty_struct *tty = port->state->port.tty; | 472 | struct tty_port *tport = &port->state->port; |
473 | struct qe_bd *bdp; | 473 | struct qe_bd *bdp; |
474 | u16 status; | 474 | u16 status; |
475 | unsigned int flg; | 475 | unsigned int flg; |
@@ -491,7 +491,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
491 | /* If we don't have enough room in RX buffer for the entire BD, | 491 | /* If we don't have enough room in RX buffer for the entire BD, |
492 | * then we try later, which will be the next RX interrupt. | 492 | * then we try later, which will be the next RX interrupt. |
493 | */ | 493 | */ |
494 | if (tty_buffer_request_room(tty, i) < i) { | 494 | if (tty_buffer_request_room(tport, i) < i) { |
495 | dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n"); | 495 | dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n"); |
496 | return; | 496 | return; |
497 | } | 497 | } |
@@ -512,7 +512,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) | |||
512 | continue; | 512 | continue; |
513 | 513 | ||
514 | error_return: | 514 | error_return: |
515 | tty_insert_flip_char(tty, ch, flg); | 515 | tty_insert_flip_char(tport, ch, flg); |
516 | 516 | ||
517 | } | 517 | } |
518 | 518 | ||
@@ -530,7 +530,7 @@ error_return: | |||
530 | qe_port->rx_cur = bdp; | 530 | qe_port->rx_cur = bdp; |
531 | 531 | ||
532 | /* Activate BH processing */ | 532 | /* Activate BH processing */ |
533 | tty_flip_buffer_push(tty); | 533 | tty_flip_buffer_push(tport); |
534 | 534 | ||
535 | return; | 535 | return; |
536 | 536 | ||
@@ -560,7 +560,7 @@ handle_error: | |||
560 | 560 | ||
561 | /* Overrun does not affect the current character ! */ | 561 | /* Overrun does not affect the current character ! */ |
562 | if (status & BD_SC_OV) | 562 | if (status & BD_SC_OV) |
563 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 563 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
564 | #ifdef SUPPORT_SYSRQ | 564 | #ifdef SUPPORT_SYSRQ |
565 | port->sysrq = 0; | 565 | port->sysrq = 0; |
566 | #endif | 566 | #endif |
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 62ee0166bc65..f655997f44af 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c | |||
@@ -313,12 +313,10 @@ static void siu_break_ctl(struct uart_port *port, int ctl) | |||
313 | 313 | ||
314 | static inline void receive_chars(struct uart_port *port, uint8_t *status) | 314 | static inline void receive_chars(struct uart_port *port, uint8_t *status) |
315 | { | 315 | { |
316 | struct tty_struct *tty; | ||
317 | uint8_t lsr, ch; | 316 | uint8_t lsr, ch; |
318 | char flag; | 317 | char flag; |
319 | int max_count = RX_MAX_COUNT; | 318 | int max_count = RX_MAX_COUNT; |
320 | 319 | ||
321 | tty = port->state->port.tty; | ||
322 | lsr = *status; | 320 | lsr = *status; |
323 | 321 | ||
324 | do { | 322 | do { |
@@ -365,7 +363,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status) | |||
365 | lsr = siu_read(port, UART_LSR); | 363 | lsr = siu_read(port, UART_LSR); |
366 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); | 364 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); |
367 | 365 | ||
368 | tty_flip_buffer_push(tty); | 366 | tty_flip_buffer_push(&port->state->port); |
369 | 367 | ||
370 | *status = lsr; | 368 | *status = lsr; |
371 | } | 369 | } |
diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index d5ed9f613005..a3f9dd5c9dff 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c | |||
@@ -136,22 +136,14 @@ static void vt8500_enable_ms(struct uart_port *port) | |||
136 | 136 | ||
137 | static void handle_rx(struct uart_port *port) | 137 | static void handle_rx(struct uart_port *port) |
138 | { | 138 | { |
139 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | 139 | struct tty_port *tport = &port->state->port; |
140 | if (!tty) { | ||
141 | /* Discard data: no tty available */ | ||
142 | int count = (vt8500_read(port, VT8500_URFIDX) & 0x1f00) >> 8; | ||
143 | u16 ch; | ||
144 | while (count--) | ||
145 | ch = readw(port->membase + VT8500_RXFIFO); | ||
146 | return; | ||
147 | } | ||
148 | 140 | ||
149 | /* | 141 | /* |
150 | * Handle overrun | 142 | * Handle overrun |
151 | */ | 143 | */ |
152 | if ((vt8500_read(port, VT8500_URISR) & RXOVER)) { | 144 | if ((vt8500_read(port, VT8500_URISR) & RXOVER)) { |
153 | port->icount.overrun++; | 145 | port->icount.overrun++; |
154 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 146 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
155 | } | 147 | } |
156 | 148 | ||
157 | /* and now the main RX loop */ | 149 | /* and now the main RX loop */ |
@@ -174,11 +166,10 @@ static void handle_rx(struct uart_port *port) | |||
174 | port->icount.rx++; | 166 | port->icount.rx++; |
175 | 167 | ||
176 | if (!uart_handle_sysrq_char(port, c)) | 168 | if (!uart_handle_sysrq_char(port, c)) |
177 | tty_insert_flip_char(tty, c, flag); | 169 | tty_insert_flip_char(tport, c, flag); |
178 | } | 170 | } |
179 | 171 | ||
180 | tty_flip_buffer_push(tty); | 172 | tty_flip_buffer_push(tport); |
181 | tty_kref_put(tty); | ||
182 | } | 173 | } |
183 | 174 | ||
184 | static void handle_tx(struct uart_port *port) | 175 | static void handle_tx(struct uart_port *port) |
@@ -569,7 +560,7 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
569 | 560 | ||
570 | if (np) | 561 | if (np) |
571 | port = of_alias_get_id(np, "serial"); | 562 | port = of_alias_get_id(np, "serial"); |
572 | if (port > VT8500_MAX_PORTS) | 563 | if (port >= VT8500_MAX_PORTS) |
573 | port = -1; | 564 | port = -1; |
574 | else | 565 | else |
575 | port = -1; | 566 | port = -1; |
@@ -580,7 +571,7 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
580 | sizeof(vt8500_ports_in_use)); | 571 | sizeof(vt8500_ports_in_use)); |
581 | } | 572 | } |
582 | 573 | ||
583 | if (port > VT8500_MAX_PORTS) | 574 | if (port >= VT8500_MAX_PORTS) |
584 | return -ENODEV; | 575 | return -ENODEV; |
585 | 576 | ||
586 | /* reserve the port id */ | 577 | /* reserve the port id */ |
@@ -589,10 +580,27 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
589 | return -EBUSY; | 580 | return -EBUSY; |
590 | } | 581 | } |
591 | 582 | ||
592 | vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL); | 583 | vt8500_port = devm_kzalloc(&pdev->dev, sizeof(struct vt8500_port), |
584 | GFP_KERNEL); | ||
593 | if (!vt8500_port) | 585 | if (!vt8500_port) |
594 | return -ENOMEM; | 586 | return -ENOMEM; |
595 | 587 | ||
588 | vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres); | ||
589 | if (!vt8500_port->uart.membase) | ||
590 | return -EADDRNOTAVAIL; | ||
591 | |||
592 | vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); | ||
593 | if (IS_ERR(vt8500_port->clk)) { | ||
594 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
595 | return -EINVAL; | ||
596 | } | ||
597 | |||
598 | ret = clk_prepare_enable(vt8500_port->clk); | ||
599 | if (ret) { | ||
600 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
601 | return ret; | ||
602 | } | ||
603 | |||
596 | vt8500_port->uart.type = PORT_VT8500; | 604 | vt8500_port->uart.type = PORT_VT8500; |
597 | vt8500_port->uart.iotype = UPIO_MEM; | 605 | vt8500_port->uart.iotype = UPIO_MEM; |
598 | vt8500_port->uart.mapbase = mmres->start; | 606 | vt8500_port->uart.mapbase = mmres->start; |
@@ -615,12 +623,6 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
615 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), | 623 | snprintf(vt8500_port->name, sizeof(vt8500_port->name), |
616 | "VT8500 UART%d", pdev->id); | 624 | "VT8500 UART%d", pdev->id); |
617 | 625 | ||
618 | vt8500_port->uart.membase = ioremap(mmres->start, resource_size(mmres)); | ||
619 | if (!vt8500_port->uart.membase) { | ||
620 | ret = -ENOMEM; | ||
621 | goto err; | ||
622 | } | ||
623 | |||
624 | vt8500_uart_ports[port] = vt8500_port; | 626 | vt8500_uart_ports[port] = vt8500_port; |
625 | 627 | ||
626 | uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); | 628 | uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart); |
@@ -628,10 +630,6 @@ static int vt8500_serial_probe(struct platform_device *pdev) | |||
628 | platform_set_drvdata(pdev, vt8500_port); | 630 | platform_set_drvdata(pdev, vt8500_port); |
629 | 631 | ||
630 | return 0; | 632 | return 0; |
631 | |||
632 | err: | ||
633 | kfree(vt8500_port); | ||
634 | return ret; | ||
635 | } | 633 | } |
636 | 634 | ||
637 | static int vt8500_serial_remove(struct platform_device *pdev) | 635 | static int vt8500_serial_remove(struct platform_device *pdev) |
@@ -639,8 +637,8 @@ static int vt8500_serial_remove(struct platform_device *pdev) | |||
639 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); | 637 | struct vt8500_port *vt8500_port = platform_get_drvdata(pdev); |
640 | 638 | ||
641 | platform_set_drvdata(pdev, NULL); | 639 | platform_set_drvdata(pdev, NULL); |
640 | clk_disable_unprepare(vt8500_port->clk); | ||
642 | uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart); | 641 | uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart); |
643 | kfree(vt8500_port); | ||
644 | 642 | ||
645 | return 0; | 643 | return 0; |
646 | } | 644 | } |
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 9ab910370c56..ba451c7209fc 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/tty.h> | 17 | #include <linux/tty.h> |
18 | #include <linux/tty_flip.h> | 18 | #include <linux/tty_flip.h> |
19 | #include <linux/console.h> | 19 | #include <linux/console.h> |
20 | #include <linux/clk.h> | ||
20 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
@@ -147,15 +148,11 @@ | |||
147 | static irqreturn_t xuartps_isr(int irq, void *dev_id) | 148 | static irqreturn_t xuartps_isr(int irq, void *dev_id) |
148 | { | 149 | { |
149 | struct uart_port *port = (struct uart_port *)dev_id; | 150 | struct uart_port *port = (struct uart_port *)dev_id; |
150 | struct tty_struct *tty; | ||
151 | unsigned long flags; | 151 | unsigned long flags; |
152 | unsigned int isrstatus, numbytes; | 152 | unsigned int isrstatus, numbytes; |
153 | unsigned int data; | 153 | unsigned int data; |
154 | char status = TTY_NORMAL; | 154 | char status = TTY_NORMAL; |
155 | 155 | ||
156 | /* Get the tty which could be NULL so don't assume it's valid */ | ||
157 | tty = tty_port_tty_get(&port->state->port); | ||
158 | |||
159 | spin_lock_irqsave(&port->lock, flags); | 156 | spin_lock_irqsave(&port->lock, flags); |
160 | 157 | ||
161 | /* Read the interrupt status register to determine which | 158 | /* Read the interrupt status register to determine which |
@@ -187,14 +184,11 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) | |||
187 | } else if (isrstatus & XUARTPS_IXR_OVERRUN) | 184 | } else if (isrstatus & XUARTPS_IXR_OVERRUN) |
188 | port->icount.overrun++; | 185 | port->icount.overrun++; |
189 | 186 | ||
190 | if (tty) | 187 | uart_insert_char(port, isrstatus, XUARTPS_IXR_OVERRUN, |
191 | uart_insert_char(port, isrstatus, | 188 | data, status); |
192 | XUARTPS_IXR_OVERRUN, data, | ||
193 | status); | ||
194 | } | 189 | } |
195 | spin_unlock(&port->lock); | 190 | spin_unlock(&port->lock); |
196 | if (tty) | 191 | tty_flip_buffer_push(&port->state->port); |
197 | tty_flip_buffer_push(tty); | ||
198 | spin_lock(&port->lock); | 192 | spin_lock(&port->lock); |
199 | } | 193 | } |
200 | 194 | ||
@@ -237,7 +231,6 @@ static irqreturn_t xuartps_isr(int irq, void *dev_id) | |||
237 | 231 | ||
238 | /* be sure to release the lock and tty before leaving */ | 232 | /* be sure to release the lock and tty before leaving */ |
239 | spin_unlock_irqrestore(&port->lock, flags); | 233 | spin_unlock_irqrestore(&port->lock, flags); |
240 | tty_kref_put(tty); | ||
241 | 234 | ||
242 | return IRQ_HANDLED; | 235 | return IRQ_HANDLED; |
243 | } | 236 | } |
@@ -944,16 +937,18 @@ static int xuartps_probe(struct platform_device *pdev) | |||
944 | int rc; | 937 | int rc; |
945 | struct uart_port *port; | 938 | struct uart_port *port; |
946 | struct resource *res, *res2; | 939 | struct resource *res, *res2; |
947 | int clk = 0; | 940 | struct clk *clk; |
948 | |||
949 | const unsigned int *prop; | ||
950 | 941 | ||
951 | prop = of_get_property(pdev->dev.of_node, "clock", NULL); | 942 | clk = of_clk_get(pdev->dev.of_node, 0); |
952 | if (prop) | 943 | if (IS_ERR(clk)) { |
953 | clk = be32_to_cpup(prop); | ||
954 | if (!clk) { | ||
955 | dev_err(&pdev->dev, "no clock specified\n"); | 944 | dev_err(&pdev->dev, "no clock specified\n"); |
956 | return -ENODEV; | 945 | return PTR_ERR(clk); |
946 | } | ||
947 | |||
948 | rc = clk_prepare_enable(clk); | ||
949 | if (rc) { | ||
950 | dev_err(&pdev->dev, "could not enable clock\n"); | ||
951 | return -EBUSY; | ||
957 | } | 952 | } |
958 | 953 | ||
959 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 954 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -978,7 +973,8 @@ static int xuartps_probe(struct platform_device *pdev) | |||
978 | port->mapbase = res->start; | 973 | port->mapbase = res->start; |
979 | port->irq = res2->start; | 974 | port->irq = res2->start; |
980 | port->dev = &pdev->dev; | 975 | port->dev = &pdev->dev; |
981 | port->uartclk = clk; | 976 | port->uartclk = clk_get_rate(clk); |
977 | port->private_data = clk; | ||
982 | dev_set_drvdata(&pdev->dev, port); | 978 | dev_set_drvdata(&pdev->dev, port); |
983 | rc = uart_add_one_port(&xuartps_uart_driver, port); | 979 | rc = uart_add_one_port(&xuartps_uart_driver, port); |
984 | if (rc) { | 980 | if (rc) { |
@@ -1000,14 +996,14 @@ static int xuartps_probe(struct platform_device *pdev) | |||
1000 | static int xuartps_remove(struct platform_device *pdev) | 996 | static int xuartps_remove(struct platform_device *pdev) |
1001 | { | 997 | { |
1002 | struct uart_port *port = dev_get_drvdata(&pdev->dev); | 998 | struct uart_port *port = dev_get_drvdata(&pdev->dev); |
1003 | int rc = 0; | 999 | struct clk *clk = port->private_data; |
1000 | int rc; | ||
1004 | 1001 | ||
1005 | /* Remove the xuartps port from the serial core */ | 1002 | /* Remove the xuartps port from the serial core */ |
1006 | if (port) { | 1003 | rc = uart_remove_one_port(&xuartps_uart_driver, port); |
1007 | rc = uart_remove_one_port(&xuartps_uart_driver, port); | 1004 | dev_set_drvdata(&pdev->dev, NULL); |
1008 | dev_set_drvdata(&pdev->dev, NULL); | 1005 | port->mapbase = 0; |
1009 | port->mapbase = 0; | 1006 | clk_disable_unprepare(clk); |
1010 | } | ||
1011 | return rc; | 1007 | return rc; |
1012 | } | 1008 | } |
1013 | 1009 | ||
@@ -1048,7 +1044,7 @@ MODULE_DEVICE_TABLE(of, xuartps_of_match); | |||
1048 | 1044 | ||
1049 | static struct platform_driver xuartps_platform_driver = { | 1045 | static struct platform_driver xuartps_platform_driver = { |
1050 | .probe = xuartps_probe, /* Probe method */ | 1046 | .probe = xuartps_probe, /* Probe method */ |
1051 | .remove = __exit_p(xuartps_remove), /* Detach method */ | 1047 | .remove = xuartps_remove, /* Detach method */ |
1052 | .suspend = xuartps_suspend, /* Suspend */ | 1048 | .suspend = xuartps_suspend, /* Suspend */ |
1053 | .resume = xuartps_resume, /* Resume after a suspend */ | 1049 | .resume = xuartps_resume, /* Resume after a suspend */ |
1054 | .driver = { | 1050 | .driver = { |
diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index 92c00b24d0df..6a169877109b 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c | |||
@@ -603,7 +603,7 @@ static void zs_receive_chars(struct zs_port *zport) | |||
603 | uart_insert_char(uport, status, Rx_OVR, ch, flag); | 603 | uart_insert_char(uport, status, Rx_OVR, ch, flag); |
604 | } | 604 | } |
605 | 605 | ||
606 | tty_flip_buffer_push(uport->state->port.tty); | 606 | tty_flip_buffer_push(&uport->state->port); |
607 | } | 607 | } |
608 | 608 | ||
609 | static void zs_raw_transmit_chars(struct zs_port *zport) | 609 | static void zs_raw_transmit_chars(struct zs_port *zport) |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 9e071f6985f6..8983276aa35e 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -291,8 +291,7 @@ struct mgsl_struct { | |||
291 | bool lcr_mem_requested; | 291 | bool lcr_mem_requested; |
292 | 292 | ||
293 | u32 misc_ctrl_value; | 293 | u32 misc_ctrl_value; |
294 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 294 | char *flag_buf; |
295 | char char_buf[MAX_ASYNC_BUFFER_SIZE]; | ||
296 | bool drop_rts_on_tx_done; | 295 | bool drop_rts_on_tx_done; |
297 | 296 | ||
298 | bool loopmode_insert_requested; | 297 | bool loopmode_insert_requested; |
@@ -1440,7 +1439,6 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1440 | u16 status; | 1439 | u16 status; |
1441 | int work = 0; | 1440 | int work = 0; |
1442 | unsigned char DataByte; | 1441 | unsigned char DataByte; |
1443 | struct tty_struct *tty = info->port.tty; | ||
1444 | struct mgsl_icount *icount = &info->icount; | 1442 | struct mgsl_icount *icount = &info->icount; |
1445 | 1443 | ||
1446 | if ( debug_level >= DEBUG_LEVEL_ISR ) | 1444 | if ( debug_level >= DEBUG_LEVEL_ISR ) |
@@ -1502,19 +1500,19 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1502 | if (status & RXSTATUS_BREAK_RECEIVED) { | 1500 | if (status & RXSTATUS_BREAK_RECEIVED) { |
1503 | flag = TTY_BREAK; | 1501 | flag = TTY_BREAK; |
1504 | if (info->port.flags & ASYNC_SAK) | 1502 | if (info->port.flags & ASYNC_SAK) |
1505 | do_SAK(tty); | 1503 | do_SAK(info->port.tty); |
1506 | } else if (status & RXSTATUS_PARITY_ERROR) | 1504 | } else if (status & RXSTATUS_PARITY_ERROR) |
1507 | flag = TTY_PARITY; | 1505 | flag = TTY_PARITY; |
1508 | else if (status & RXSTATUS_FRAMING_ERROR) | 1506 | else if (status & RXSTATUS_FRAMING_ERROR) |
1509 | flag = TTY_FRAME; | 1507 | flag = TTY_FRAME; |
1510 | } /* end of if (error) */ | 1508 | } /* end of if (error) */ |
1511 | tty_insert_flip_char(tty, DataByte, flag); | 1509 | tty_insert_flip_char(&info->port, DataByte, flag); |
1512 | if (status & RXSTATUS_OVERRUN) { | 1510 | if (status & RXSTATUS_OVERRUN) { |
1513 | /* Overrun is special, since it's | 1511 | /* Overrun is special, since it's |
1514 | * reported immediately, and doesn't | 1512 | * reported immediately, and doesn't |
1515 | * affect the current character | 1513 | * affect the current character |
1516 | */ | 1514 | */ |
1517 | work += tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1515 | work += tty_insert_flip_char(&info->port, 0, TTY_OVERRUN); |
1518 | } | 1516 | } |
1519 | } | 1517 | } |
1520 | 1518 | ||
@@ -1525,7 +1523,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) | |||
1525 | } | 1523 | } |
1526 | 1524 | ||
1527 | if(work) | 1525 | if(work) |
1528 | tty_flip_buffer_push(tty); | 1526 | tty_flip_buffer_push(&info->port); |
1529 | } | 1527 | } |
1530 | 1528 | ||
1531 | /* mgsl_isr_misc() | 1529 | /* mgsl_isr_misc() |
@@ -1852,7 +1850,7 @@ static void shutdown(struct mgsl_struct * info) | |||
1852 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); | 1850 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); |
1853 | 1851 | ||
1854 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { | 1852 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
1855 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 1853 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1856 | usc_set_serial_signals(info); | 1854 | usc_set_serial_signals(info); |
1857 | } | 1855 | } |
1858 | 1856 | ||
@@ -1917,12 +1915,12 @@ static void mgsl_change_params(struct mgsl_struct *info) | |||
1917 | 1915 | ||
1918 | cflag = info->port.tty->termios.c_cflag; | 1916 | cflag = info->port.tty->termios.c_cflag; |
1919 | 1917 | ||
1920 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 1918 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
1921 | /* otherwise assert DTR and RTS */ | 1919 | /* otherwise assert RTS and DTR */ |
1922 | if (cflag & CBAUD) | 1920 | if (cflag & CBAUD) |
1923 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 1921 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
1924 | else | 1922 | else |
1925 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 1923 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
1926 | 1924 | ||
1927 | /* byte size and parity */ | 1925 | /* byte size and parity */ |
1928 | 1926 | ||
@@ -3046,7 +3044,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
3046 | /* Handle transition to B0 status */ | 3044 | /* Handle transition to B0 status */ |
3047 | if (old_termios->c_cflag & CBAUD && | 3045 | if (old_termios->c_cflag & CBAUD && |
3048 | !(tty->termios.c_cflag & CBAUD)) { | 3046 | !(tty->termios.c_cflag & CBAUD)) { |
3049 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3047 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3050 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3048 | spin_lock_irqsave(&info->irq_spinlock,flags); |
3051 | usc_set_serial_signals(info); | 3049 | usc_set_serial_signals(info); |
3052 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 3050 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
@@ -3245,9 +3243,9 @@ static void dtr_rts(struct tty_port *port, int on) | |||
3245 | 3243 | ||
3246 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3244 | spin_lock_irqsave(&info->irq_spinlock,flags); |
3247 | if (on) | 3245 | if (on) |
3248 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 3246 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
3249 | else | 3247 | else |
3250 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3248 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3251 | usc_set_serial_signals(info); | 3249 | usc_set_serial_signals(info); |
3252 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 3250 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
3253 | } | 3251 | } |
@@ -3416,7 +3414,7 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp) | |||
3416 | goto cleanup; | 3414 | goto cleanup; |
3417 | } | 3415 | } |
3418 | 3416 | ||
3419 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 3417 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
3420 | 3418 | ||
3421 | spin_lock_irqsave(&info->netlock, flags); | 3419 | spin_lock_irqsave(&info->netlock, flags); |
3422 | if (info->netcount) { | 3420 | if (info->netcount) { |
@@ -3898,7 +3896,13 @@ static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info) | |||
3898 | info->intermediate_rxbuffer = kmalloc(info->max_frame_size, GFP_KERNEL | GFP_DMA); | 3896 | info->intermediate_rxbuffer = kmalloc(info->max_frame_size, GFP_KERNEL | GFP_DMA); |
3899 | if ( info->intermediate_rxbuffer == NULL ) | 3897 | if ( info->intermediate_rxbuffer == NULL ) |
3900 | return -ENOMEM; | 3898 | return -ENOMEM; |
3901 | 3899 | /* unused flag buffer to satisfy receive_buf calling interface */ | |
3900 | info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL); | ||
3901 | if (!info->flag_buf) { | ||
3902 | kfree(info->intermediate_rxbuffer); | ||
3903 | info->intermediate_rxbuffer = NULL; | ||
3904 | return -ENOMEM; | ||
3905 | } | ||
3902 | return 0; | 3906 | return 0; |
3903 | 3907 | ||
3904 | } /* end of mgsl_alloc_intermediate_rxbuffer_memory() */ | 3908 | } /* end of mgsl_alloc_intermediate_rxbuffer_memory() */ |
@@ -3917,6 +3921,8 @@ static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info) | |||
3917 | { | 3921 | { |
3918 | kfree(info->intermediate_rxbuffer); | 3922 | kfree(info->intermediate_rxbuffer); |
3919 | info->intermediate_rxbuffer = NULL; | 3923 | info->intermediate_rxbuffer = NULL; |
3924 | kfree(info->flag_buf); | ||
3925 | info->flag_buf = NULL; | ||
3920 | 3926 | ||
3921 | } /* end of mgsl_free_intermediate_rxbuffer_memory() */ | 3927 | } /* end of mgsl_free_intermediate_rxbuffer_memory() */ |
3922 | 3928 | ||
@@ -6233,8 +6239,8 @@ static void usc_get_serial_signals( struct mgsl_struct *info ) | |||
6233 | { | 6239 | { |
6234 | u16 status; | 6240 | u16 status; |
6235 | 6241 | ||
6236 | /* clear all serial signals except DTR and RTS */ | 6242 | /* clear all serial signals except RTS and DTR */ |
6237 | info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; | 6243 | info->serial_signals &= SerialSignal_RTS | SerialSignal_DTR; |
6238 | 6244 | ||
6239 | /* Read the Misc Interrupt status Register (MISR) to get */ | 6245 | /* Read the Misc Interrupt status Register (MISR) to get */ |
6240 | /* the V24 status signals. */ | 6246 | /* the V24 status signals. */ |
@@ -6259,7 +6265,7 @@ static void usc_get_serial_signals( struct mgsl_struct *info ) | |||
6259 | 6265 | ||
6260 | /* usc_set_serial_signals() | 6266 | /* usc_set_serial_signals() |
6261 | * | 6267 | * |
6262 | * Set the state of DTR and RTS based on contents of | 6268 | * Set the state of RTS and DTR based on contents of |
6263 | * serial_signals member of device extension. | 6269 | * serial_signals member of device extension. |
6264 | * | 6270 | * |
6265 | * Arguments: info pointer to device instance data | 6271 | * Arguments: info pointer to device instance data |
@@ -7773,8 +7779,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
7773 | return rc; | 7779 | return rc; |
7774 | } | 7780 | } |
7775 | 7781 | ||
7776 | /* assert DTR and RTS, apply hardware settings */ | 7782 | /* assert RTS and DTR, apply hardware settings */ |
7777 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 7783 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
7778 | mgsl_program_hw(info); | 7784 | mgsl_program_hw(info); |
7779 | 7785 | ||
7780 | /* enable network layer transmit */ | 7786 | /* enable network layer transmit */ |
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index aba1e59f4a88..aa9eece35c3b 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -317,8 +317,7 @@ struct slgt_info { | |||
317 | unsigned char *tx_buf; | 317 | unsigned char *tx_buf; |
318 | int tx_count; | 318 | int tx_count; |
319 | 319 | ||
320 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 320 | char *flag_buf; |
321 | char char_buf[MAX_ASYNC_BUFFER_SIZE]; | ||
322 | bool drop_rts_on_tx_done; | 321 | bool drop_rts_on_tx_done; |
323 | struct _input_signal_events input_signal_events; | 322 | struct _input_signal_events input_signal_events; |
324 | 323 | ||
@@ -683,7 +682,7 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
683 | } | 682 | } |
684 | 683 | ||
685 | mutex_lock(&info->port.mutex); | 684 | mutex_lock(&info->port.mutex); |
686 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 685 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
687 | 686 | ||
688 | spin_lock_irqsave(&info->netlock, flags); | 687 | spin_lock_irqsave(&info->netlock, flags); |
689 | if (info->netcount) { | 688 | if (info->netcount) { |
@@ -786,7 +785,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
786 | /* Handle transition to B0 status */ | 785 | /* Handle transition to B0 status */ |
787 | if (old_termios->c_cflag & CBAUD && | 786 | if (old_termios->c_cflag & CBAUD && |
788 | !(tty->termios.c_cflag & CBAUD)) { | 787 | !(tty->termios.c_cflag & CBAUD)) { |
789 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 788 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
790 | spin_lock_irqsave(&info->lock,flags); | 789 | spin_lock_irqsave(&info->lock,flags); |
791 | set_signals(info); | 790 | set_signals(info); |
792 | spin_unlock_irqrestore(&info->lock,flags); | 791 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -1561,8 +1560,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
1561 | return rc; | 1560 | return rc; |
1562 | } | 1561 | } |
1563 | 1562 | ||
1564 | /* assert DTR and RTS, apply hardware settings */ | 1563 | /* assert RTS and DTR, apply hardware settings */ |
1565 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 1564 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
1566 | program_hw(info); | 1565 | program_hw(info); |
1567 | 1566 | ||
1568 | /* enable network layer transmit */ | 1567 | /* enable network layer transmit */ |
@@ -1855,7 +1854,6 @@ static void hdlcdev_exit(struct slgt_info *info) | |||
1855 | */ | 1854 | */ |
1856 | static void rx_async(struct slgt_info *info) | 1855 | static void rx_async(struct slgt_info *info) |
1857 | { | 1856 | { |
1858 | struct tty_struct *tty = info->port.tty; | ||
1859 | struct mgsl_icount *icount = &info->icount; | 1857 | struct mgsl_icount *icount = &info->icount; |
1860 | unsigned int start, end; | 1858 | unsigned int start, end; |
1861 | unsigned char *p; | 1859 | unsigned char *p; |
@@ -1894,10 +1892,8 @@ static void rx_async(struct slgt_info *info) | |||
1894 | else if (status & BIT0) | 1892 | else if (status & BIT0) |
1895 | stat = TTY_FRAME; | 1893 | stat = TTY_FRAME; |
1896 | } | 1894 | } |
1897 | if (tty) { | 1895 | tty_insert_flip_char(&info->port, ch, stat); |
1898 | tty_insert_flip_char(tty, ch, stat); | 1896 | chars++; |
1899 | chars++; | ||
1900 | } | ||
1901 | } | 1897 | } |
1902 | 1898 | ||
1903 | if (i < count) { | 1899 | if (i < count) { |
@@ -1918,8 +1914,8 @@ static void rx_async(struct slgt_info *info) | |||
1918 | break; | 1914 | break; |
1919 | } | 1915 | } |
1920 | 1916 | ||
1921 | if (tty && chars) | 1917 | if (chars) |
1922 | tty_flip_buffer_push(tty); | 1918 | tty_flip_buffer_push(&info->port); |
1923 | } | 1919 | } |
1924 | 1920 | ||
1925 | /* | 1921 | /* |
@@ -1961,8 +1957,6 @@ static void bh_handler(struct work_struct *work) | |||
1961 | struct slgt_info *info = container_of(work, struct slgt_info, task); | 1957 | struct slgt_info *info = container_of(work, struct slgt_info, task); |
1962 | int action; | 1958 | int action; |
1963 | 1959 | ||
1964 | if (!info) | ||
1965 | return; | ||
1966 | info->bh_running = true; | 1960 | info->bh_running = true; |
1967 | 1961 | ||
1968 | while((action = bh_action(info))) { | 1962 | while((action = bh_action(info))) { |
@@ -2183,7 +2177,7 @@ static void isr_serial(struct slgt_info *info) | |||
2183 | if (info->port.tty) { | 2177 | if (info->port.tty) { |
2184 | if (!(status & info->ignore_status_mask)) { | 2178 | if (!(status & info->ignore_status_mask)) { |
2185 | if (info->read_status_mask & MASK_BREAK) { | 2179 | if (info->read_status_mask & MASK_BREAK) { |
2186 | tty_insert_flip_char(info->port.tty, 0, TTY_BREAK); | 2180 | tty_insert_flip_char(&info->port, 0, TTY_BREAK); |
2187 | if (info->port.flags & ASYNC_SAK) | 2181 | if (info->port.flags & ASYNC_SAK) |
2188 | do_SAK(info->port.tty); | 2182 | do_SAK(info->port.tty); |
2189 | } | 2183 | } |
@@ -2494,7 +2488,7 @@ static void shutdown(struct slgt_info *info) | |||
2494 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); | 2488 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); |
2495 | 2489 | ||
2496 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { | 2490 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
2497 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2491 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2498 | set_signals(info); | 2492 | set_signals(info); |
2499 | } | 2493 | } |
2500 | 2494 | ||
@@ -2554,12 +2548,12 @@ static void change_params(struct slgt_info *info) | |||
2554 | 2548 | ||
2555 | cflag = info->port.tty->termios.c_cflag; | 2549 | cflag = info->port.tty->termios.c_cflag; |
2556 | 2550 | ||
2557 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2551 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
2558 | /* otherwise assert DTR and RTS */ | 2552 | /* otherwise assert RTS and DTR */ |
2559 | if (cflag & CBAUD) | 2553 | if (cflag & CBAUD) |
2560 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 2554 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
2561 | else | 2555 | else |
2562 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2556 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2563 | 2557 | ||
2564 | /* byte size and parity */ | 2558 | /* byte size and parity */ |
2565 | 2559 | ||
@@ -3262,9 +3256,9 @@ static void dtr_rts(struct tty_port *port, int on) | |||
3262 | 3256 | ||
3263 | spin_lock_irqsave(&info->lock,flags); | 3257 | spin_lock_irqsave(&info->lock,flags); |
3264 | if (on) | 3258 | if (on) |
3265 | info->signals |= SerialSignal_RTS + SerialSignal_DTR; | 3259 | info->signals |= SerialSignal_RTS | SerialSignal_DTR; |
3266 | else | 3260 | else |
3267 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3261 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3268 | set_signals(info); | 3262 | set_signals(info); |
3269 | spin_unlock_irqrestore(&info->lock,flags); | 3263 | spin_unlock_irqrestore(&info->lock,flags); |
3270 | } | 3264 | } |
@@ -3355,11 +3349,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3355 | return retval; | 3349 | return retval; |
3356 | } | 3350 | } |
3357 | 3351 | ||
3352 | /* | ||
3353 | * allocate buffers used for calling line discipline receive_buf | ||
3354 | * directly in synchronous mode | ||
3355 | * note: add 5 bytes to max frame size to allow appending | ||
3356 | * 32-bit CRC and status byte when configured to do so | ||
3357 | */ | ||
3358 | static int alloc_tmp_rbuf(struct slgt_info *info) | 3358 | static int alloc_tmp_rbuf(struct slgt_info *info) |
3359 | { | 3359 | { |
3360 | info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); | 3360 | info->tmp_rbuf = kmalloc(info->max_frame_size + 5, GFP_KERNEL); |
3361 | if (info->tmp_rbuf == NULL) | 3361 | if (info->tmp_rbuf == NULL) |
3362 | return -ENOMEM; | 3362 | return -ENOMEM; |
3363 | /* unused flag buffer to satisfy receive_buf calling interface */ | ||
3364 | info->flag_buf = kzalloc(info->max_frame_size + 5, GFP_KERNEL); | ||
3365 | if (!info->flag_buf) { | ||
3366 | kfree(info->tmp_rbuf); | ||
3367 | info->tmp_rbuf = NULL; | ||
3368 | return -ENOMEM; | ||
3369 | } | ||
3363 | return 0; | 3370 | return 0; |
3364 | } | 3371 | } |
3365 | 3372 | ||
@@ -3367,6 +3374,8 @@ static void free_tmp_rbuf(struct slgt_info *info) | |||
3367 | { | 3374 | { |
3368 | kfree(info->tmp_rbuf); | 3375 | kfree(info->tmp_rbuf); |
3369 | info->tmp_rbuf = NULL; | 3376 | info->tmp_rbuf = NULL; |
3377 | kfree(info->flag_buf); | ||
3378 | info->flag_buf = NULL; | ||
3370 | } | 3379 | } |
3371 | 3380 | ||
3372 | /* | 3381 | /* |
@@ -4110,7 +4119,7 @@ static void reset_port(struct slgt_info *info) | |||
4110 | tx_stop(info); | 4119 | tx_stop(info); |
4111 | rx_stop(info); | 4120 | rx_stop(info); |
4112 | 4121 | ||
4113 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 4122 | info->signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
4114 | set_signals(info); | 4123 | set_signals(info); |
4115 | 4124 | ||
4116 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); | 4125 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); |
@@ -4537,8 +4546,8 @@ static void get_signals(struct slgt_info *info) | |||
4537 | { | 4546 | { |
4538 | unsigned short status = rd_reg16(info, SSR); | 4547 | unsigned short status = rd_reg16(info, SSR); |
4539 | 4548 | ||
4540 | /* clear all serial signals except DTR and RTS */ | 4549 | /* clear all serial signals except RTS and DTR */ |
4541 | info->signals &= SerialSignal_DTR + SerialSignal_RTS; | 4550 | info->signals &= SerialSignal_RTS | SerialSignal_DTR; |
4542 | 4551 | ||
4543 | if (status & BIT3) | 4552 | if (status & BIT3) |
4544 | info->signals |= SerialSignal_DSR; | 4553 | info->signals |= SerialSignal_DSR; |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index fd43fb6f7cee..6d5780cf1d57 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
@@ -262,8 +262,7 @@ typedef struct _synclinkmp_info { | |||
262 | bool sca_statctrl_requested; | 262 | bool sca_statctrl_requested; |
263 | 263 | ||
264 | u32 misc_ctrl_value; | 264 | u32 misc_ctrl_value; |
265 | char flag_buf[MAX_ASYNC_BUFFER_SIZE]; | 265 | char *flag_buf; |
266 | char char_buf[MAX_ASYNC_BUFFER_SIZE]; | ||
267 | bool drop_rts_on_tx_done; | 266 | bool drop_rts_on_tx_done; |
268 | 267 | ||
269 | struct _input_signal_events input_signal_events; | 268 | struct _input_signal_events input_signal_events; |
@@ -762,7 +761,7 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
762 | goto cleanup; | 761 | goto cleanup; |
763 | } | 762 | } |
764 | 763 | ||
765 | info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; | 764 | info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; |
766 | 765 | ||
767 | spin_lock_irqsave(&info->netlock, flags); | 766 | spin_lock_irqsave(&info->netlock, flags); |
768 | if (info->netcount) { | 767 | if (info->netcount) { |
@@ -883,7 +882,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
883 | /* Handle transition to B0 status */ | 882 | /* Handle transition to B0 status */ |
884 | if (old_termios->c_cflag & CBAUD && | 883 | if (old_termios->c_cflag & CBAUD && |
885 | !(tty->termios.c_cflag & CBAUD)) { | 884 | !(tty->termios.c_cflag & CBAUD)) { |
886 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 885 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
887 | spin_lock_irqsave(&info->lock,flags); | 886 | spin_lock_irqsave(&info->lock,flags); |
888 | set_signals(info); | 887 | set_signals(info); |
889 | spin_unlock_irqrestore(&info->lock,flags); | 888 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -1677,8 +1676,8 @@ static int hdlcdev_open(struct net_device *dev) | |||
1677 | return rc; | 1676 | return rc; |
1678 | } | 1677 | } |
1679 | 1678 | ||
1680 | /* assert DTR and RTS, apply hardware settings */ | 1679 | /* assert RTS and DTR, apply hardware settings */ |
1681 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 1680 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
1682 | program_hw(info); | 1681 | program_hw(info); |
1683 | 1682 | ||
1684 | /* enable network layer transmit */ | 1683 | /* enable network layer transmit */ |
@@ -2008,9 +2007,6 @@ static void bh_handler(struct work_struct *work) | |||
2008 | SLMP_INFO *info = container_of(work, SLMP_INFO, task); | 2007 | SLMP_INFO *info = container_of(work, SLMP_INFO, task); |
2009 | int action; | 2008 | int action; |
2010 | 2009 | ||
2011 | if (!info) | ||
2012 | return; | ||
2013 | |||
2014 | if ( debug_level >= DEBUG_LEVEL_BH ) | 2010 | if ( debug_level >= DEBUG_LEVEL_BH ) |
2015 | printk( "%s(%d):%s bh_handler() entry\n", | 2011 | printk( "%s(%d):%s bh_handler() entry\n", |
2016 | __FILE__,__LINE__,info->device_name); | 2012 | __FILE__,__LINE__,info->device_name); |
@@ -2132,13 +2128,11 @@ static void isr_rxint(SLMP_INFO * info) | |||
2132 | /* process break detection if tty control | 2128 | /* process break detection if tty control |
2133 | * is not set to ignore it | 2129 | * is not set to ignore it |
2134 | */ | 2130 | */ |
2135 | if ( tty ) { | 2131 | if (!(status & info->ignore_status_mask1)) { |
2136 | if (!(status & info->ignore_status_mask1)) { | 2132 | if (info->read_status_mask1 & BRKD) { |
2137 | if (info->read_status_mask1 & BRKD) { | 2133 | tty_insert_flip_char(&info->port, 0, TTY_BREAK); |
2138 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 2134 | if (tty && (info->port.flags & ASYNC_SAK)) |
2139 | if (info->port.flags & ASYNC_SAK) | 2135 | do_SAK(tty); |
2140 | do_SAK(tty); | ||
2141 | } | ||
2142 | } | 2136 | } |
2143 | } | 2137 | } |
2144 | } | 2138 | } |
@@ -2170,7 +2164,6 @@ static void isr_rxrdy(SLMP_INFO * info) | |||
2170 | { | 2164 | { |
2171 | u16 status; | 2165 | u16 status; |
2172 | unsigned char DataByte; | 2166 | unsigned char DataByte; |
2173 | struct tty_struct *tty = info->port.tty; | ||
2174 | struct mgsl_icount *icount = &info->icount; | 2167 | struct mgsl_icount *icount = &info->icount; |
2175 | 2168 | ||
2176 | if ( debug_level >= DEBUG_LEVEL_ISR ) | 2169 | if ( debug_level >= DEBUG_LEVEL_ISR ) |
@@ -2203,26 +2196,22 @@ static void isr_rxrdy(SLMP_INFO * info) | |||
2203 | 2196 | ||
2204 | status &= info->read_status_mask2; | 2197 | status &= info->read_status_mask2; |
2205 | 2198 | ||
2206 | if ( tty ) { | 2199 | if (status & PE) |
2207 | if (status & PE) | 2200 | flag = TTY_PARITY; |
2208 | flag = TTY_PARITY; | 2201 | else if (status & FRME) |
2209 | else if (status & FRME) | 2202 | flag = TTY_FRAME; |
2210 | flag = TTY_FRAME; | 2203 | if (status & OVRN) { |
2211 | if (status & OVRN) { | 2204 | /* Overrun is special, since it's |
2212 | /* Overrun is special, since it's | 2205 | * reported immediately, and doesn't |
2213 | * reported immediately, and doesn't | 2206 | * affect the current character |
2214 | * affect the current character | 2207 | */ |
2215 | */ | 2208 | over = true; |
2216 | over = true; | ||
2217 | } | ||
2218 | } | 2209 | } |
2219 | } /* end of if (error) */ | 2210 | } /* end of if (error) */ |
2220 | 2211 | ||
2221 | if ( tty ) { | 2212 | tty_insert_flip_char(&info->port, DataByte, flag); |
2222 | tty_insert_flip_char(tty, DataByte, flag); | 2213 | if (over) |
2223 | if (over) | 2214 | tty_insert_flip_char(&info->port, 0, TTY_OVERRUN); |
2224 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
2225 | } | ||
2226 | } | 2215 | } |
2227 | 2216 | ||
2228 | if ( debug_level >= DEBUG_LEVEL_ISR ) { | 2217 | if ( debug_level >= DEBUG_LEVEL_ISR ) { |
@@ -2232,8 +2221,7 @@ static void isr_rxrdy(SLMP_INFO * info) | |||
2232 | icount->frame,icount->overrun); | 2221 | icount->frame,icount->overrun); |
2233 | } | 2222 | } |
2234 | 2223 | ||
2235 | if ( tty ) | 2224 | tty_flip_buffer_push(&info->port); |
2236 | tty_flip_buffer_push(tty); | ||
2237 | } | 2225 | } |
2238 | 2226 | ||
2239 | static void isr_txeom(SLMP_INFO * info, unsigned char status) | 2227 | static void isr_txeom(SLMP_INFO * info, unsigned char status) |
@@ -2718,7 +2706,7 @@ static void shutdown(SLMP_INFO * info) | |||
2718 | reset_port(info); | 2706 | reset_port(info); |
2719 | 2707 | ||
2720 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { | 2708 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
2721 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2709 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2722 | set_signals(info); | 2710 | set_signals(info); |
2723 | } | 2711 | } |
2724 | 2712 | ||
@@ -2780,12 +2768,12 @@ static void change_params(SLMP_INFO *info) | |||
2780 | 2768 | ||
2781 | cflag = info->port.tty->termios.c_cflag; | 2769 | cflag = info->port.tty->termios.c_cflag; |
2782 | 2770 | ||
2783 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2771 | /* if B0 rate (hangup) specified then negate RTS and DTR */ |
2784 | /* otherwise assert DTR and RTS */ | 2772 | /* otherwise assert RTS and DTR */ |
2785 | if (cflag & CBAUD) | 2773 | if (cflag & CBAUD) |
2786 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 2774 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
2787 | else | 2775 | else |
2788 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2776 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
2789 | 2777 | ||
2790 | /* byte size and parity */ | 2778 | /* byte size and parity */ |
2791 | 2779 | ||
@@ -3224,12 +3212,12 @@ static int tiocmget(struct tty_struct *tty) | |||
3224 | get_signals(info); | 3212 | get_signals(info); |
3225 | spin_unlock_irqrestore(&info->lock,flags); | 3213 | spin_unlock_irqrestore(&info->lock,flags); |
3226 | 3214 | ||
3227 | result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS:0) + | 3215 | result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS : 0) | |
3228 | ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR:0) + | 3216 | ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR : 0) | |
3229 | ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR:0) + | 3217 | ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR : 0) | |
3230 | ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG:0) + | 3218 | ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG : 0) | |
3231 | ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR:0) + | 3219 | ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR : 0) | |
3232 | ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS:0); | 3220 | ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS : 0); |
3233 | 3221 | ||
3234 | if (debug_level >= DEBUG_LEVEL_INFO) | 3222 | if (debug_level >= DEBUG_LEVEL_INFO) |
3235 | printk("%s(%d):%s tiocmget() value=%08X\n", | 3223 | printk("%s(%d):%s tiocmget() value=%08X\n", |
@@ -3284,9 +3272,9 @@ static void dtr_rts(struct tty_port *port, int on) | |||
3284 | 3272 | ||
3285 | spin_lock_irqsave(&info->lock,flags); | 3273 | spin_lock_irqsave(&info->lock,flags); |
3286 | if (on) | 3274 | if (on) |
3287 | info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; | 3275 | info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR; |
3288 | else | 3276 | else |
3289 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3277 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
3290 | set_signals(info); | 3278 | set_signals(info); |
3291 | spin_unlock_irqrestore(&info->lock,flags); | 3279 | spin_unlock_irqrestore(&info->lock,flags); |
3292 | } | 3280 | } |
@@ -3553,6 +3541,13 @@ static int alloc_tmp_rx_buf(SLMP_INFO *info) | |||
3553 | info->tmp_rx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); | 3541 | info->tmp_rx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); |
3554 | if (info->tmp_rx_buf == NULL) | 3542 | if (info->tmp_rx_buf == NULL) |
3555 | return -ENOMEM; | 3543 | return -ENOMEM; |
3544 | /* unused flag buffer to satisfy receive_buf calling interface */ | ||
3545 | info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL); | ||
3546 | if (!info->flag_buf) { | ||
3547 | kfree(info->tmp_rx_buf); | ||
3548 | info->tmp_rx_buf = NULL; | ||
3549 | return -ENOMEM; | ||
3550 | } | ||
3556 | return 0; | 3551 | return 0; |
3557 | } | 3552 | } |
3558 | 3553 | ||
@@ -3560,6 +3555,8 @@ static void free_tmp_rx_buf(SLMP_INFO *info) | |||
3560 | { | 3555 | { |
3561 | kfree(info->tmp_rx_buf); | 3556 | kfree(info->tmp_rx_buf); |
3562 | info->tmp_rx_buf = NULL; | 3557 | info->tmp_rx_buf = NULL; |
3558 | kfree(info->flag_buf); | ||
3559 | info->flag_buf = NULL; | ||
3563 | } | 3560 | } |
3564 | 3561 | ||
3565 | static int claim_resources(SLMP_INFO *info) | 3562 | static int claim_resources(SLMP_INFO *info) |
@@ -4357,7 +4354,7 @@ static void reset_port(SLMP_INFO *info) | |||
4357 | tx_stop(info); | 4354 | tx_stop(info); |
4358 | rx_stop(info); | 4355 | rx_stop(info); |
4359 | 4356 | ||
4360 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 4357 | info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR); |
4361 | set_signals(info); | 4358 | set_signals(info); |
4362 | 4359 | ||
4363 | /* disable all port interrupts */ | 4360 | /* disable all port interrupts */ |
@@ -4753,8 +4750,8 @@ static void get_signals(SLMP_INFO *info) | |||
4753 | u16 gpstatus = read_status_reg(info); | 4750 | u16 gpstatus = read_status_reg(info); |
4754 | u16 testbit; | 4751 | u16 testbit; |
4755 | 4752 | ||
4756 | /* clear all serial signals except DTR and RTS */ | 4753 | /* clear all serial signals except RTS and DTR */ |
4757 | info->serial_signals &= SerialSignal_DTR + SerialSignal_RTS; | 4754 | info->serial_signals &= SerialSignal_RTS | SerialSignal_DTR; |
4758 | 4755 | ||
4759 | /* set serial signal bits to reflect MISR */ | 4756 | /* set serial signal bits to reflect MISR */ |
4760 | 4757 | ||
@@ -4773,7 +4770,7 @@ static void get_signals(SLMP_INFO *info) | |||
4773 | info->serial_signals |= SerialSignal_DSR; | 4770 | info->serial_signals |= SerialSignal_DSR; |
4774 | } | 4771 | } |
4775 | 4772 | ||
4776 | /* Set the state of DTR and RTS based on contents of | 4773 | /* Set the state of RTS and DTR based on contents of |
4777 | * serial_signals member of device context. | 4774 | * serial_signals member of device context. |
4778 | */ | 4775 | */ |
4779 | static void set_signals(SLMP_INFO *info) | 4776 | static void set_signals(SLMP_INFO *info) |
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 45d916198f78..bb119934e76c 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/ratelimit.h> | ||
19 | 20 | ||
20 | /** | 21 | /** |
21 | * tty_buffer_free_all - free buffers used by a tty | 22 | * tty_buffer_free_all - free buffers used by a tty |
@@ -119,11 +120,14 @@ static void __tty_buffer_flush(struct tty_port *port) | |||
119 | struct tty_bufhead *buf = &port->buf; | 120 | struct tty_bufhead *buf = &port->buf; |
120 | struct tty_buffer *thead; | 121 | struct tty_buffer *thead; |
121 | 122 | ||
122 | while ((thead = buf->head) != NULL) { | 123 | if (unlikely(buf->head == NULL)) |
123 | buf->head = thead->next; | 124 | return; |
124 | tty_buffer_free(port, thead); | 125 | while ((thead = buf->head->next) != NULL) { |
126 | tty_buffer_free(port, buf->head); | ||
127 | buf->head = thead; | ||
125 | } | 128 | } |
126 | buf->tail = NULL; | 129 | WARN_ON(buf->head != buf->tail); |
130 | buf->head->read = buf->head->commit; | ||
127 | } | 131 | } |
128 | 132 | ||
129 | /** | 133 | /** |
@@ -194,19 +198,22 @@ static struct tty_buffer *tty_buffer_find(struct tty_port *port, size_t size) | |||
194 | have queued and recycle that ? */ | 198 | have queued and recycle that ? */ |
195 | } | 199 | } |
196 | /** | 200 | /** |
197 | * __tty_buffer_request_room - grow tty buffer if needed | 201 | * tty_buffer_request_room - grow tty buffer if needed |
198 | * @tty: tty structure | 202 | * @tty: tty structure |
199 | * @size: size desired | 203 | * @size: size desired |
200 | * | 204 | * |
201 | * Make at least size bytes of linear space available for the tty | 205 | * Make at least size bytes of linear space available for the tty |
202 | * buffer. If we fail return the size we managed to find. | 206 | * buffer. If we fail return the size we managed to find. |
203 | * Locking: Caller must hold port->buf.lock | 207 | * |
208 | * Locking: Takes port->buf.lock | ||
204 | */ | 209 | */ |
205 | static int __tty_buffer_request_room(struct tty_port *port, size_t size) | 210 | int tty_buffer_request_room(struct tty_port *port, size_t size) |
206 | { | 211 | { |
207 | struct tty_bufhead *buf = &port->buf; | 212 | struct tty_bufhead *buf = &port->buf; |
208 | struct tty_buffer *b, *n; | 213 | struct tty_buffer *b, *n; |
209 | int left; | 214 | int left; |
215 | unsigned long flags; | ||
216 | spin_lock_irqsave(&buf->lock, flags); | ||
210 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | 217 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to |
211 | remove this conditional if its worth it. This would be invisible | 218 | remove this conditional if its worth it. This would be invisible |
212 | to the callers */ | 219 | to the callers */ |
@@ -228,37 +235,14 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size) | |||
228 | } else | 235 | } else |
229 | size = left; | 236 | size = left; |
230 | } | 237 | } |
231 | 238 | spin_unlock_irqrestore(&buf->lock, flags); | |
232 | return size; | 239 | return size; |
233 | } | 240 | } |
234 | |||
235 | |||
236 | /** | ||
237 | * tty_buffer_request_room - grow tty buffer if needed | ||
238 | * @tty: tty structure | ||
239 | * @size: size desired | ||
240 | * | ||
241 | * Make at least size bytes of linear space available for the tty | ||
242 | * buffer. If we fail return the size we managed to find. | ||
243 | * | ||
244 | * Locking: Takes port->buf.lock | ||
245 | */ | ||
246 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | ||
247 | { | ||
248 | struct tty_port *port = tty->port; | ||
249 | unsigned long flags; | ||
250 | int length; | ||
251 | |||
252 | spin_lock_irqsave(&port->buf.lock, flags); | ||
253 | length = __tty_buffer_request_room(port, size); | ||
254 | spin_unlock_irqrestore(&port->buf.lock, flags); | ||
255 | return length; | ||
256 | } | ||
257 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); | 241 | EXPORT_SYMBOL_GPL(tty_buffer_request_room); |
258 | 242 | ||
259 | /** | 243 | /** |
260 | * tty_insert_flip_string_fixed_flag - Add characters to the tty buffer | 244 | * tty_insert_flip_string_fixed_flag - Add characters to the tty buffer |
261 | * @tty: tty structure | 245 | * @port: tty port |
262 | * @chars: characters | 246 | * @chars: characters |
263 | * @flag: flag value for each character | 247 | * @flag: flag value for each character |
264 | * @size: size | 248 | * @size: size |
@@ -269,29 +253,21 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); | |||
269 | * Locking: Called functions may take port->buf.lock | 253 | * Locking: Called functions may take port->buf.lock |
270 | */ | 254 | */ |
271 | 255 | ||
272 | int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, | 256 | int tty_insert_flip_string_fixed_flag(struct tty_port *port, |
273 | const unsigned char *chars, char flag, size_t size) | 257 | const unsigned char *chars, char flag, size_t size) |
274 | { | 258 | { |
275 | struct tty_bufhead *buf = &tty->port->buf; | ||
276 | int copied = 0; | 259 | int copied = 0; |
277 | do { | 260 | do { |
278 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); | 261 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
279 | int space; | 262 | int space = tty_buffer_request_room(port, goal); |
280 | unsigned long flags; | 263 | struct tty_buffer *tb = port->buf.tail; |
281 | struct tty_buffer *tb; | ||
282 | |||
283 | spin_lock_irqsave(&buf->lock, flags); | ||
284 | space = __tty_buffer_request_room(tty->port, goal); | ||
285 | tb = buf->tail; | ||
286 | /* If there is no space then tb may be NULL */ | 264 | /* If there is no space then tb may be NULL */ |
287 | if (unlikely(space == 0)) { | 265 | if (unlikely(space == 0)) { |
288 | spin_unlock_irqrestore(&buf->lock, flags); | ||
289 | break; | 266 | break; |
290 | } | 267 | } |
291 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 268 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
292 | memset(tb->flag_buf_ptr + tb->used, flag, space); | 269 | memset(tb->flag_buf_ptr + tb->used, flag, space); |
293 | tb->used += space; | 270 | tb->used += space; |
294 | spin_unlock_irqrestore(&buf->lock, flags); | ||
295 | copied += space; | 271 | copied += space; |
296 | chars += space; | 272 | chars += space; |
297 | /* There is a small chance that we need to split the data over | 273 | /* There is a small chance that we need to split the data over |
@@ -303,7 +279,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); | |||
303 | 279 | ||
304 | /** | 280 | /** |
305 | * tty_insert_flip_string_flags - Add characters to the tty buffer | 281 | * tty_insert_flip_string_flags - Add characters to the tty buffer |
306 | * @tty: tty structure | 282 | * @port: tty port |
307 | * @chars: characters | 283 | * @chars: characters |
308 | * @flags: flag bytes | 284 | * @flags: flag bytes |
309 | * @size: size | 285 | * @size: size |
@@ -315,29 +291,21 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); | |||
315 | * Locking: Called functions may take port->buf.lock | 291 | * Locking: Called functions may take port->buf.lock |
316 | */ | 292 | */ |
317 | 293 | ||
318 | int tty_insert_flip_string_flags(struct tty_struct *tty, | 294 | int tty_insert_flip_string_flags(struct tty_port *port, |
319 | const unsigned char *chars, const char *flags, size_t size) | 295 | const unsigned char *chars, const char *flags, size_t size) |
320 | { | 296 | { |
321 | struct tty_bufhead *buf = &tty->port->buf; | ||
322 | int copied = 0; | 297 | int copied = 0; |
323 | do { | 298 | do { |
324 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); | 299 | int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); |
325 | int space; | 300 | int space = tty_buffer_request_room(port, goal); |
326 | unsigned long __flags; | 301 | struct tty_buffer *tb = port->buf.tail; |
327 | struct tty_buffer *tb; | ||
328 | |||
329 | spin_lock_irqsave(&buf->lock, __flags); | ||
330 | space = __tty_buffer_request_room(tty->port, goal); | ||
331 | tb = buf->tail; | ||
332 | /* If there is no space then tb may be NULL */ | 302 | /* If there is no space then tb may be NULL */ |
333 | if (unlikely(space == 0)) { | 303 | if (unlikely(space == 0)) { |
334 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
335 | break; | 304 | break; |
336 | } | 305 | } |
337 | memcpy(tb->char_buf_ptr + tb->used, chars, space); | 306 | memcpy(tb->char_buf_ptr + tb->used, chars, space); |
338 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); | 307 | memcpy(tb->flag_buf_ptr + tb->used, flags, space); |
339 | tb->used += space; | 308 | tb->used += space; |
340 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
341 | copied += space; | 309 | copied += space; |
342 | chars += space; | 310 | chars += space; |
343 | flags += space; | 311 | flags += space; |
@@ -350,7 +318,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); | |||
350 | 318 | ||
351 | /** | 319 | /** |
352 | * tty_schedule_flip - push characters to ldisc | 320 | * tty_schedule_flip - push characters to ldisc |
353 | * @tty: tty to push from | 321 | * @port: tty port to push from |
354 | * | 322 | * |
355 | * Takes any pending buffers and transfers their ownership to the | 323 | * Takes any pending buffers and transfers their ownership to the |
356 | * ldisc side of the queue. It then schedules those characters for | 324 | * ldisc side of the queue. It then schedules those characters for |
@@ -361,11 +329,11 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); | |||
361 | * Locking: Takes port->buf.lock | 329 | * Locking: Takes port->buf.lock |
362 | */ | 330 | */ |
363 | 331 | ||
364 | void tty_schedule_flip(struct tty_struct *tty) | 332 | void tty_schedule_flip(struct tty_port *port) |
365 | { | 333 | { |
366 | struct tty_bufhead *buf = &tty->port->buf; | 334 | struct tty_bufhead *buf = &port->buf; |
367 | unsigned long flags; | 335 | unsigned long flags; |
368 | WARN_ON(tty->low_latency); | 336 | WARN_ON(port->low_latency); |
369 | 337 | ||
370 | spin_lock_irqsave(&buf->lock, flags); | 338 | spin_lock_irqsave(&buf->lock, flags); |
371 | if (buf->tail != NULL) | 339 | if (buf->tail != NULL) |
@@ -377,7 +345,7 @@ EXPORT_SYMBOL(tty_schedule_flip); | |||
377 | 345 | ||
378 | /** | 346 | /** |
379 | * tty_prepare_flip_string - make room for characters | 347 | * tty_prepare_flip_string - make room for characters |
380 | * @tty: tty | 348 | * @port: tty port |
381 | * @chars: return pointer for character write area | 349 | * @chars: return pointer for character write area |
382 | * @size: desired size | 350 | * @size: desired size |
383 | * | 351 | * |
@@ -390,31 +358,23 @@ EXPORT_SYMBOL(tty_schedule_flip); | |||
390 | * Locking: May call functions taking port->buf.lock | 358 | * Locking: May call functions taking port->buf.lock |
391 | */ | 359 | */ |
392 | 360 | ||
393 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, | 361 | int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, |
394 | size_t size) | 362 | size_t size) |
395 | { | 363 | { |
396 | struct tty_bufhead *buf = &tty->port->buf; | 364 | int space = tty_buffer_request_room(port, size); |
397 | int space; | ||
398 | unsigned long flags; | ||
399 | struct tty_buffer *tb; | ||
400 | |||
401 | spin_lock_irqsave(&buf->lock, flags); | ||
402 | space = __tty_buffer_request_room(tty->port, size); | ||
403 | |||
404 | tb = buf->tail; | ||
405 | if (likely(space)) { | 365 | if (likely(space)) { |
366 | struct tty_buffer *tb = port->buf.tail; | ||
406 | *chars = tb->char_buf_ptr + tb->used; | 367 | *chars = tb->char_buf_ptr + tb->used; |
407 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | 368 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); |
408 | tb->used += space; | 369 | tb->used += space; |
409 | } | 370 | } |
410 | spin_unlock_irqrestore(&buf->lock, flags); | ||
411 | return space; | 371 | return space; |
412 | } | 372 | } |
413 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | 373 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string); |
414 | 374 | ||
415 | /** | 375 | /** |
416 | * tty_prepare_flip_string_flags - make room for characters | 376 | * tty_prepare_flip_string_flags - make room for characters |
417 | * @tty: tty | 377 | * @port: tty port |
418 | * @chars: return pointer for character write area | 378 | * @chars: return pointer for character write area |
419 | * @flags: return pointer for status flag write area | 379 | * @flags: return pointer for status flag write area |
420 | * @size: desired size | 380 | * @size: desired size |
@@ -428,24 +388,16 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | |||
428 | * Locking: May call functions taking port->buf.lock | 388 | * Locking: May call functions taking port->buf.lock |
429 | */ | 389 | */ |
430 | 390 | ||
431 | int tty_prepare_flip_string_flags(struct tty_struct *tty, | 391 | int tty_prepare_flip_string_flags(struct tty_port *port, |
432 | unsigned char **chars, char **flags, size_t size) | 392 | unsigned char **chars, char **flags, size_t size) |
433 | { | 393 | { |
434 | struct tty_bufhead *buf = &tty->port->buf; | 394 | int space = tty_buffer_request_room(port, size); |
435 | int space; | ||
436 | unsigned long __flags; | ||
437 | struct tty_buffer *tb; | ||
438 | |||
439 | spin_lock_irqsave(&buf->lock, __flags); | ||
440 | space = __tty_buffer_request_room(tty->port, size); | ||
441 | |||
442 | tb = buf->tail; | ||
443 | if (likely(space)) { | 395 | if (likely(space)) { |
396 | struct tty_buffer *tb = port->buf.tail; | ||
444 | *chars = tb->char_buf_ptr + tb->used; | 397 | *chars = tb->char_buf_ptr + tb->used; |
445 | *flags = tb->flag_buf_ptr + tb->used; | 398 | *flags = tb->flag_buf_ptr + tb->used; |
446 | tb->used += space; | 399 | tb->used += space; |
447 | } | 400 | } |
448 | spin_unlock_irqrestore(&buf->lock, __flags); | ||
449 | return space; | 401 | return space; |
450 | } | 402 | } |
451 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | 403 | EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); |
@@ -539,16 +491,17 @@ static void flush_to_ldisc(struct work_struct *work) | |||
539 | */ | 491 | */ |
540 | void tty_flush_to_ldisc(struct tty_struct *tty) | 492 | void tty_flush_to_ldisc(struct tty_struct *tty) |
541 | { | 493 | { |
542 | if (!tty->low_latency) | 494 | if (!tty->port->low_latency) |
543 | flush_work(&tty->port->buf.work); | 495 | flush_work(&tty->port->buf.work); |
544 | } | 496 | } |
545 | 497 | ||
546 | /** | 498 | /** |
547 | * tty_flip_buffer_push - terminal | 499 | * tty_flip_buffer_push - terminal |
548 | * @tty: tty to push | 500 | * @port: tty port to push |
549 | * | 501 | * |
550 | * Queue a push of the terminal flip buffers to the line discipline. This | 502 | * Queue a push of the terminal flip buffers to the line discipline. This |
551 | * function must not be called from IRQ context if tty->low_latency is set. | 503 | * function must not be called from IRQ context if port->low_latency is |
504 | * set. | ||
552 | * | 505 | * |
553 | * In the event of the queue being busy for flipping the work will be | 506 | * In the event of the queue being busy for flipping the work will be |
554 | * held off and retried later. | 507 | * held off and retried later. |
@@ -556,9 +509,9 @@ void tty_flush_to_ldisc(struct tty_struct *tty) | |||
556 | * Locking: tty buffer lock. Driver locks in low latency mode. | 509 | * Locking: tty buffer lock. Driver locks in low latency mode. |
557 | */ | 510 | */ |
558 | 511 | ||
559 | void tty_flip_buffer_push(struct tty_struct *tty) | 512 | void tty_flip_buffer_push(struct tty_port *port) |
560 | { | 513 | { |
561 | struct tty_bufhead *buf = &tty->port->buf; | 514 | struct tty_bufhead *buf = &port->buf; |
562 | unsigned long flags; | 515 | unsigned long flags; |
563 | 516 | ||
564 | spin_lock_irqsave(&buf->lock, flags); | 517 | spin_lock_irqsave(&buf->lock, flags); |
@@ -566,7 +519,7 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
566 | buf->tail->commit = buf->tail->used; | 519 | buf->tail->commit = buf->tail->used; |
567 | spin_unlock_irqrestore(&buf->lock, flags); | 520 | spin_unlock_irqrestore(&buf->lock, flags); |
568 | 521 | ||
569 | if (tty->low_latency) | 522 | if (port->low_latency) |
570 | flush_to_ldisc(&buf->work); | 523 | flush_to_ldisc(&buf->work); |
571 | else | 524 | else |
572 | schedule_work(&buf->work); | 525 | schedule_work(&buf->work); |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 6b20fd66d4ad..60e48a11b66c 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -536,7 +536,7 @@ EXPORT_SYMBOL_GPL(tty_wakeup); | |||
536 | * __tty_hangup - actual handler for hangup events | 536 | * __tty_hangup - actual handler for hangup events |
537 | * @work: tty device | 537 | * @work: tty device |
538 | * | 538 | * |
539 | * This can be called by the "eventd" kernel thread. That is process | 539 | * This can be called by a "kworker" kernel thread. That is process |
540 | * synchronous but doesn't hold any locks, so we need to make sure we | 540 | * synchronous but doesn't hold any locks, so we need to make sure we |
541 | * have the appropriate locks for what we're doing. | 541 | * have the appropriate locks for what we're doing. |
542 | * | 542 | * |
@@ -977,8 +977,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
977 | else | 977 | else |
978 | i = -EIO; | 978 | i = -EIO; |
979 | tty_ldisc_deref(ld); | 979 | tty_ldisc_deref(ld); |
980 | if (i > 0) | 980 | |
981 | inode->i_atime = current_fs_time(inode->i_sb); | ||
982 | return i; | 981 | return i; |
983 | } | 982 | } |
984 | 983 | ||
@@ -1079,11 +1078,8 @@ static inline ssize_t do_tty_write( | |||
1079 | break; | 1078 | break; |
1080 | cond_resched(); | 1079 | cond_resched(); |
1081 | } | 1080 | } |
1082 | if (written) { | 1081 | if (written) |
1083 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1084 | inode->i_mtime = current_fs_time(inode->i_sb); | ||
1085 | ret = written; | 1082 | ret = written; |
1086 | } | ||
1087 | out: | 1083 | out: |
1088 | tty_write_unlock(tty); | 1084 | tty_write_unlock(tty); |
1089 | return ret; | 1085 | return ret; |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 8481b29d5b3a..d58b92cc187c 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -617,7 +617,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | |||
617 | if (opt & TERMIOS_WAIT) { | 617 | if (opt & TERMIOS_WAIT) { |
618 | tty_wait_until_sent(tty, 0); | 618 | tty_wait_until_sent(tty, 0); |
619 | if (signal_pending(current)) | 619 | if (signal_pending(current)) |
620 | return -EINTR; | 620 | return -ERESTARTSYS; |
621 | } | 621 | } |
622 | 622 | ||
623 | tty_set_termios(tty, &tmp_termios); | 623 | tty_set_termios(tty, &tmp_termios); |
@@ -684,7 +684,7 @@ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) | |||
684 | if (opt & TERMIOS_WAIT) { | 684 | if (opt & TERMIOS_WAIT) { |
685 | tty_wait_until_sent(tty, 0); | 685 | tty_wait_until_sent(tty, 0); |
686 | if (signal_pending(current)) | 686 | if (signal_pending(current)) |
687 | return -EINTR; | 687 | return -ERESTARTSYS; |
688 | } | 688 | } |
689 | 689 | ||
690 | mutex_lock(&tty->termios_mutex); | 690 | mutex_lock(&tty->termios_mutex); |
@@ -1096,12 +1096,16 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg) | |||
1096 | ld = tty_ldisc_ref_wait(tty); | 1096 | ld = tty_ldisc_ref_wait(tty); |
1097 | switch (arg) { | 1097 | switch (arg) { |
1098 | case TCIFLUSH: | 1098 | case TCIFLUSH: |
1099 | if (ld && ld->ops->flush_buffer) | 1099 | if (ld && ld->ops->flush_buffer) { |
1100 | ld->ops->flush_buffer(tty); | 1100 | ld->ops->flush_buffer(tty); |
1101 | tty_unthrottle(tty); | ||
1102 | } | ||
1101 | break; | 1103 | break; |
1102 | case TCIOFLUSH: | 1104 | case TCIOFLUSH: |
1103 | if (ld && ld->ops->flush_buffer) | 1105 | if (ld && ld->ops->flush_buffer) { |
1104 | ld->ops->flush_buffer(tty); | 1106 | ld->ops->flush_buffer(tty); |
1107 | tty_unthrottle(tty); | ||
1108 | } | ||
1105 | /* fall through */ | 1109 | /* fall through */ |
1106 | case TCOFLUSH: | 1110 | case TCOFLUSH: |
1107 | tty_driver_flush_buffer(tty); | 1111 | tty_driver_flush_buffer(tty); |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index c5782294e532..d794087c327e 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -64,7 +64,9 @@ static void put_ldisc(struct tty_ldisc *ld) | |||
64 | return; | 64 | return; |
65 | } | 65 | } |
66 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 66 | raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
67 | wake_up(&ld->wq_idle); | 67 | |
68 | if (waitqueue_active(&ld->wq_idle)) | ||
69 | wake_up(&ld->wq_idle); | ||
68 | } | 70 | } |
69 | 71 | ||
70 | /** | 72 | /** |
@@ -934,17 +936,17 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
934 | * race with the set_ldisc code path. | 936 | * race with the set_ldisc code path. |
935 | */ | 937 | */ |
936 | 938 | ||
937 | tty_lock_pair(tty, o_tty); | ||
938 | tty_ldisc_halt(tty); | 939 | tty_ldisc_halt(tty); |
939 | tty_ldisc_flush_works(tty); | 940 | if (o_tty) |
940 | if (o_tty) { | ||
941 | tty_ldisc_halt(o_tty); | 941 | tty_ldisc_halt(o_tty); |
942 | |||
943 | tty_ldisc_flush_works(tty); | ||
944 | if (o_tty) | ||
942 | tty_ldisc_flush_works(o_tty); | 945 | tty_ldisc_flush_works(o_tty); |
943 | } | ||
944 | 946 | ||
947 | tty_lock_pair(tty, o_tty); | ||
945 | /* This will need doing differently if we need to lock */ | 948 | /* This will need doing differently if we need to lock */ |
946 | tty_ldisc_kill(tty); | 949 | tty_ldisc_kill(tty); |
947 | |||
948 | if (o_tty) | 950 | if (o_tty) |
949 | tty_ldisc_kill(o_tty); | 951 | tty_ldisc_kill(o_tty); |
950 | 952 | ||
diff --git a/drivers/tty/vt/Makefile b/drivers/tty/vt/Makefile index 14a51c9960df..17ae94cb29f8 100644 --- a/drivers/tty/vt/Makefile +++ b/drivers/tty/vt/Makefile | |||
@@ -27,8 +27,6 @@ $(obj)/defkeymap.o: $(obj)/defkeymap.c | |||
27 | ifdef GENERATE_KEYMAP | 27 | ifdef GENERATE_KEYMAP |
28 | 28 | ||
29 | $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map | 29 | $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map |
30 | loadkeys --mktable $< > $@.tmp | 30 | loadkeys --mktable $< > $@ |
31 | sed -e 's/^static *//' $@.tmp > $@ | ||
32 | rm $@.tmp | ||
33 | 31 | ||
34 | endif | 32 | endif |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 681765baef69..a9af1b9ae160 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -307,26 +307,17 @@ int kbd_rate(struct kbd_repeat *rep) | |||
307 | */ | 307 | */ |
308 | static void put_queue(struct vc_data *vc, int ch) | 308 | static void put_queue(struct vc_data *vc, int ch) |
309 | { | 309 | { |
310 | struct tty_struct *tty = vc->port.tty; | 310 | tty_insert_flip_char(&vc->port, ch, 0); |
311 | 311 | tty_schedule_flip(&vc->port); | |
312 | if (tty) { | ||
313 | tty_insert_flip_char(tty, ch, 0); | ||
314 | tty_schedule_flip(tty); | ||
315 | } | ||
316 | } | 312 | } |
317 | 313 | ||
318 | static void puts_queue(struct vc_data *vc, char *cp) | 314 | static void puts_queue(struct vc_data *vc, char *cp) |
319 | { | 315 | { |
320 | struct tty_struct *tty = vc->port.tty; | ||
321 | |||
322 | if (!tty) | ||
323 | return; | ||
324 | |||
325 | while (*cp) { | 316 | while (*cp) { |
326 | tty_insert_flip_char(tty, *cp, 0); | 317 | tty_insert_flip_char(&vc->port, *cp, 0); |
327 | cp++; | 318 | cp++; |
328 | } | 319 | } |
329 | tty_schedule_flip(tty); | 320 | tty_schedule_flip(&vc->port); |
330 | } | 321 | } |
331 | 322 | ||
332 | static void applkey(struct vc_data *vc, int key, char mode) | 323 | static void applkey(struct vc_data *vc, int key, char mode) |
@@ -582,12 +573,8 @@ static void fn_inc_console(struct vc_data *vc) | |||
582 | 573 | ||
583 | static void fn_send_intr(struct vc_data *vc) | 574 | static void fn_send_intr(struct vc_data *vc) |
584 | { | 575 | { |
585 | struct tty_struct *tty = vc->port.tty; | 576 | tty_insert_flip_char(&vc->port, 0, TTY_BREAK); |
586 | 577 | tty_schedule_flip(&vc->port); | |
587 | if (!tty) | ||
588 | return; | ||
589 | tty_insert_flip_char(tty, 0, TTY_BREAK); | ||
590 | tty_schedule_flip(tty); | ||
591 | } | 578 | } |
592 | 579 | ||
593 | static void fn_scroll_forw(struct vc_data *vc) | 580 | static void fn_scroll_forw(struct vc_data *vc) |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 8fd89687d068..1a2728034599 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -1333,13 +1333,13 @@ static void csi_m(struct vc_data *vc) | |||
1333 | update_attr(vc); | 1333 | update_attr(vc); |
1334 | } | 1334 | } |
1335 | 1335 | ||
1336 | static void respond_string(const char *p, struct tty_struct *tty) | 1336 | static void respond_string(const char *p, struct tty_port *port) |
1337 | { | 1337 | { |
1338 | while (*p) { | 1338 | while (*p) { |
1339 | tty_insert_flip_char(tty, *p, 0); | 1339 | tty_insert_flip_char(port, *p, 0); |
1340 | p++; | 1340 | p++; |
1341 | } | 1341 | } |
1342 | tty_schedule_flip(tty); | 1342 | tty_schedule_flip(port); |
1343 | } | 1343 | } |
1344 | 1344 | ||
1345 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) | 1345 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) |
@@ -1347,17 +1347,17 @@ static void cursor_report(struct vc_data *vc, struct tty_struct *tty) | |||
1347 | char buf[40]; | 1347 | char buf[40]; |
1348 | 1348 | ||
1349 | sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1); | 1349 | sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1); |
1350 | respond_string(buf, tty); | 1350 | respond_string(buf, tty->port); |
1351 | } | 1351 | } |
1352 | 1352 | ||
1353 | static inline void status_report(struct tty_struct *tty) | 1353 | static inline void status_report(struct tty_struct *tty) |
1354 | { | 1354 | { |
1355 | respond_string("\033[0n", tty); /* Terminal ok */ | 1355 | respond_string("\033[0n", tty->port); /* Terminal ok */ |
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | static inline void respond_ID(struct tty_struct * tty) | 1358 | static inline void respond_ID(struct tty_struct *tty) |
1359 | { | 1359 | { |
1360 | respond_string(VT102ID, tty); | 1360 | respond_string(VT102ID, tty->port); |
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry) | 1363 | void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry) |
@@ -1366,7 +1366,7 @@ void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry) | |||
1366 | 1366 | ||
1367 | sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx), | 1367 | sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx), |
1368 | (char)('!' + mry)); | 1368 | (char)('!' + mry)); |
1369 | respond_string(buf, tty); | 1369 | respond_string(buf, tty->port); |
1370 | } | 1370 | } |
1371 | 1371 | ||
1372 | /* invoked via ioctl(TIOCLINUX) and through set_selection */ | 1372 | /* invoked via ioctl(TIOCLINUX) and through set_selection */ |
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 2519e320098f..316aac8e4ca1 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig | |||
@@ -6,7 +6,7 @@ comment "USB Device Class drivers" | |||
6 | 6 | ||
7 | config USB_ACM | 7 | config USB_ACM |
8 | tristate "USB Modem (CDC ACM) support" | 8 | tristate "USB Modem (CDC ACM) support" |
9 | depends on USB | 9 | depends on USB && TTY |
10 | ---help--- | 10 | ---help--- |
11 | This driver supports USB modems and ISDN adapters which support the | 11 | This driver supports USB modems and ISDN adapters which support the |
12 | Communication Device Class Abstract Control Model interface. | 12 | Communication Device Class Abstract Control Model interface. |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 2d92cce260d7..8ac25adf31b4 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -410,19 +410,12 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags) | |||
410 | 410 | ||
411 | static void acm_process_read_urb(struct acm *acm, struct urb *urb) | 411 | static void acm_process_read_urb(struct acm *acm, struct urb *urb) |
412 | { | 412 | { |
413 | struct tty_struct *tty; | ||
414 | |||
415 | if (!urb->actual_length) | 413 | if (!urb->actual_length) |
416 | return; | 414 | return; |
417 | 415 | ||
418 | tty = tty_port_tty_get(&acm->port); | 416 | tty_insert_flip_string(&acm->port, urb->transfer_buffer, |
419 | if (!tty) | 417 | urb->actual_length); |
420 | return; | 418 | tty_flip_buffer_push(&acm->port); |
421 | |||
422 | tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length); | ||
423 | tty_flip_buffer_push(tty); | ||
424 | |||
425 | tty_kref_put(tty); | ||
426 | } | 419 | } |
427 | 420 | ||
428 | static void acm_read_bulk_callback(struct urb *urb) | 421 | static void acm_read_bulk_callback(struct urb *urb) |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index c5c6fa60910d..5a0c541daf89 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -762,6 +762,7 @@ config USB_GADGET_TARGET | |||
762 | 762 | ||
763 | config USB_G_SERIAL | 763 | config USB_G_SERIAL |
764 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" | 764 | tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" |
765 | depends on TTY | ||
765 | select USB_U_SERIAL | 766 | select USB_U_SERIAL |
766 | select USB_F_ACM | 767 | select USB_F_ACM |
767 | select USB_LIBCOMPOSITE | 768 | select USB_LIBCOMPOSITE |
@@ -813,6 +814,8 @@ config USB_G_PRINTER | |||
813 | For more information, see Documentation/usb/gadget_printer.txt | 814 | For more information, see Documentation/usb/gadget_printer.txt |
814 | which includes sample code for accessing the device file. | 815 | which includes sample code for accessing the device file. |
815 | 816 | ||
817 | if TTY | ||
818 | |||
816 | config USB_CDC_COMPOSITE | 819 | config USB_CDC_COMPOSITE |
817 | tristate "CDC Composite Device (Ethernet and ACM)" | 820 | tristate "CDC Composite Device (Ethernet and ACM)" |
818 | depends on NET | 821 | depends on NET |
@@ -900,6 +903,8 @@ config USB_G_MULTI_CDC | |||
900 | 903 | ||
901 | If unsure, say "y". | 904 | If unsure, say "y". |
902 | 905 | ||
906 | endif # TTY | ||
907 | |||
903 | config USB_G_HID | 908 | config USB_G_HID |
904 | tristate "HID Gadget" | 909 | tristate "HID Gadget" |
905 | select USB_LIBCOMPOSITE | 910 | select USB_LIBCOMPOSITE |
@@ -916,6 +921,7 @@ config USB_G_HID | |||
916 | # Standalone / single function gadgets | 921 | # Standalone / single function gadgets |
917 | config USB_G_DBGP | 922 | config USB_G_DBGP |
918 | tristate "EHCI Debug Device Gadget" | 923 | tristate "EHCI Debug Device Gadget" |
924 | depends on TTY | ||
919 | select USB_LIBCOMPOSITE | 925 | select USB_LIBCOMPOSITE |
920 | help | 926 | help |
921 | This gadget emulates an EHCI Debug device. This is useful when you want | 927 | This gadget emulates an EHCI Debug device. This is useful when you want |
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 588a9be18ef8..c5034d9c946b 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -496,12 +496,8 @@ static void gs_rx_push(unsigned long _port) | |||
496 | 496 | ||
497 | req = list_first_entry(queue, struct usb_request, list); | 497 | req = list_first_entry(queue, struct usb_request, list); |
498 | 498 | ||
499 | /* discard data if tty was closed */ | ||
500 | if (!tty) | ||
501 | goto recycle; | ||
502 | |||
503 | /* leave data queued if tty was rx throttled */ | 499 | /* leave data queued if tty was rx throttled */ |
504 | if (test_bit(TTY_THROTTLED, &tty->flags)) | 500 | if (tty && test_bit(TTY_THROTTLED, &tty->flags)) |
505 | break; | 501 | break; |
506 | 502 | ||
507 | switch (req->status) { | 503 | switch (req->status) { |
@@ -534,7 +530,8 @@ static void gs_rx_push(unsigned long _port) | |||
534 | size -= n; | 530 | size -= n; |
535 | } | 531 | } |
536 | 532 | ||
537 | count = tty_insert_flip_string(tty, packet, size); | 533 | count = tty_insert_flip_string(&port->port, packet, |
534 | size); | ||
538 | if (count) | 535 | if (count) |
539 | do_push = true; | 536 | do_push = true; |
540 | if (count != size) { | 537 | if (count != size) { |
@@ -547,7 +544,7 @@ static void gs_rx_push(unsigned long _port) | |||
547 | } | 544 | } |
548 | port->n_read = 0; | 545 | port->n_read = 0; |
549 | } | 546 | } |
550 | recycle: | 547 | |
551 | list_move(&req->list, &port->read_pool); | 548 | list_move(&req->list, &port->read_pool); |
552 | port->read_started--; | 549 | port->read_started--; |
553 | } | 550 | } |
@@ -555,8 +552,8 @@ recycle: | |||
555 | /* Push from tty to ldisc; without low_latency set this is handled by | 552 | /* Push from tty to ldisc; without low_latency set this is handled by |
556 | * a workqueue, so we won't get callbacks and can hold port_lock | 553 | * a workqueue, so we won't get callbacks and can hold port_lock |
557 | */ | 554 | */ |
558 | if (tty && do_push) | 555 | if (do_push) |
559 | tty_flip_buffer_push(tty); | 556 | tty_flip_buffer_push(&port->port); |
560 | 557 | ||
561 | 558 | ||
562 | /* We want our data queue to become empty ASAP, keeping data | 559 | /* We want our data queue to become empty ASAP, keeping data |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index dad8363e5b2a..17b7f9ae36ad 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | menuconfig USB_SERIAL | 5 | menuconfig USB_SERIAL |
6 | tristate "USB Serial Converter support" | 6 | tristate "USB Serial Converter support" |
7 | depends on USB | 7 | depends on USB && TTY |
8 | ---help--- | 8 | ---help--- |
9 | Say Y here if you have a USB device that provides normal serial | 9 | Say Y here if you have a USB device that provides normal serial |
10 | ports, or acts like a serial device, and you want to connect it to | 10 | ports, or acts like a serial device, and you want to connect it to |
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 6d110a3bc7e7..6e320cec397d 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -119,9 +119,8 @@ static int aircable_probe(struct usb_serial *serial, | |||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | static int aircable_process_packet(struct tty_struct *tty, | 122 | static int aircable_process_packet(struct usb_serial_port *port, |
123 | struct usb_serial_port *port, int has_headers, | 123 | int has_headers, char *packet, int len) |
124 | char *packet, int len) | ||
125 | { | 124 | { |
126 | if (has_headers) { | 125 | if (has_headers) { |
127 | len -= HCI_HEADER_LENGTH; | 126 | len -= HCI_HEADER_LENGTH; |
@@ -132,7 +131,7 @@ static int aircable_process_packet(struct tty_struct *tty, | |||
132 | return 0; | 131 | return 0; |
133 | } | 132 | } |
134 | 133 | ||
135 | tty_insert_flip_string(tty, packet, len); | 134 | tty_insert_flip_string(&port->port, packet, len); |
136 | 135 | ||
137 | return len; | 136 | return len; |
138 | } | 137 | } |
@@ -141,28 +140,22 @@ static void aircable_process_read_urb(struct urb *urb) | |||
141 | { | 140 | { |
142 | struct usb_serial_port *port = urb->context; | 141 | struct usb_serial_port *port = urb->context; |
143 | char *data = (char *)urb->transfer_buffer; | 142 | char *data = (char *)urb->transfer_buffer; |
144 | struct tty_struct *tty; | ||
145 | int has_headers; | 143 | int has_headers; |
146 | int count; | 144 | int count; |
147 | int len; | 145 | int len; |
148 | int i; | 146 | int i; |
149 | 147 | ||
150 | tty = tty_port_tty_get(&port->port); | ||
151 | if (!tty) | ||
152 | return; | ||
153 | |||
154 | has_headers = (urb->actual_length > 2 && data[0] == RX_HEADER_0); | 148 | has_headers = (urb->actual_length > 2 && data[0] == RX_HEADER_0); |
155 | 149 | ||
156 | count = 0; | 150 | count = 0; |
157 | for (i = 0; i < urb->actual_length; i += HCI_COMPLETE_FRAME) { | 151 | for (i = 0; i < urb->actual_length; i += HCI_COMPLETE_FRAME) { |
158 | len = min_t(int, urb->actual_length - i, HCI_COMPLETE_FRAME); | 152 | len = min_t(int, urb->actual_length - i, HCI_COMPLETE_FRAME); |
159 | count += aircable_process_packet(tty, port, has_headers, | 153 | count += aircable_process_packet(port, has_headers, |
160 | &data[i], len); | 154 | &data[i], len); |
161 | } | 155 | } |
162 | 156 | ||
163 | if (count) | 157 | if (count) |
164 | tty_flip_buffer_push(tty); | 158 | tty_flip_buffer_push(&port->port); |
165 | tty_kref_put(tty); | ||
166 | } | 159 | } |
167 | 160 | ||
168 | static struct usb_serial_driver aircable_device = { | 161 | static struct usb_serial_driver aircable_device = { |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index a88882c0e237..cbd904b8fba5 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -674,7 +674,6 @@ static void ark3116_process_read_urb(struct urb *urb) | |||
674 | { | 674 | { |
675 | struct usb_serial_port *port = urb->context; | 675 | struct usb_serial_port *port = urb->context; |
676 | struct ark3116_private *priv = usb_get_serial_port_data(port); | 676 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
677 | struct tty_struct *tty; | ||
678 | unsigned char *data = urb->transfer_buffer; | 677 | unsigned char *data = urb->transfer_buffer; |
679 | char tty_flag = TTY_NORMAL; | 678 | char tty_flag = TTY_NORMAL; |
680 | unsigned long flags; | 679 | unsigned long flags; |
@@ -689,10 +688,6 @@ static void ark3116_process_read_urb(struct urb *urb) | |||
689 | if (!urb->actual_length) | 688 | if (!urb->actual_length) |
690 | return; | 689 | return; |
691 | 690 | ||
692 | tty = tty_port_tty_get(&port->port); | ||
693 | if (!tty) | ||
694 | return; | ||
695 | |||
696 | if (lsr & UART_LSR_BRK_ERROR_BITS) { | 691 | if (lsr & UART_LSR_BRK_ERROR_BITS) { |
697 | if (lsr & UART_LSR_BI) | 692 | if (lsr & UART_LSR_BI) |
698 | tty_flag = TTY_BREAK; | 693 | tty_flag = TTY_BREAK; |
@@ -703,12 +698,11 @@ static void ark3116_process_read_urb(struct urb *urb) | |||
703 | 698 | ||
704 | /* overrun is special, not associated with a char */ | 699 | /* overrun is special, not associated with a char */ |
705 | if (lsr & UART_LSR_OE) | 700 | if (lsr & UART_LSR_OE) |
706 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 701 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
707 | } | 702 | } |
708 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 703 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
709 | urb->actual_length); | 704 | urb->actual_length); |
710 | tty_flip_buffer_push(tty); | 705 | tty_flip_buffer_push(&port->port); |
711 | tty_kref_put(tty); | ||
712 | } | 706 | } |
713 | 707 | ||
714 | static struct usb_serial_driver ark3116_device = { | 708 | static struct usb_serial_driver ark3116_device = { |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index b72a4c166705..84217e78ded4 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -242,7 +242,6 @@ static void belkin_sa_process_read_urb(struct urb *urb) | |||
242 | { | 242 | { |
243 | struct usb_serial_port *port = urb->context; | 243 | struct usb_serial_port *port = urb->context; |
244 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); | 244 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); |
245 | struct tty_struct *tty; | ||
246 | unsigned char *data = urb->transfer_buffer; | 245 | unsigned char *data = urb->transfer_buffer; |
247 | unsigned long flags; | 246 | unsigned long flags; |
248 | unsigned char status; | 247 | unsigned char status; |
@@ -259,10 +258,6 @@ static void belkin_sa_process_read_urb(struct urb *urb) | |||
259 | if (!urb->actual_length) | 258 | if (!urb->actual_length) |
260 | return; | 259 | return; |
261 | 260 | ||
262 | tty = tty_port_tty_get(&port->port); | ||
263 | if (!tty) | ||
264 | return; | ||
265 | |||
266 | if (status & BELKIN_SA_LSR_ERR) { | 261 | if (status & BELKIN_SA_LSR_ERR) { |
267 | /* Break takes precedence over parity, which takes precedence | 262 | /* Break takes precedence over parity, which takes precedence |
268 | * over framing errors. */ | 263 | * over framing errors. */ |
@@ -276,13 +271,12 @@ static void belkin_sa_process_read_urb(struct urb *urb) | |||
276 | 271 | ||
277 | /* Overrun is special, not associated with a char. */ | 272 | /* Overrun is special, not associated with a char. */ |
278 | if (status & BELKIN_SA_LSR_OE) | 273 | if (status & BELKIN_SA_LSR_OE) |
279 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 274 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
280 | } | 275 | } |
281 | 276 | ||
282 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 277 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
283 | urb->actual_length); | 278 | urb->actual_length); |
284 | tty_flip_buffer_push(tty); | 279 | tty_flip_buffer_push(&port->port); |
285 | tty_kref_put(tty); | ||
286 | } | 280 | } |
287 | 281 | ||
288 | static void belkin_sa_set_termios(struct tty_struct *tty, | 282 | static void belkin_sa_set_termios(struct tty_struct *tty, |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 69a4fa1cee25..629bd2894506 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -324,7 +324,6 @@ static void cyberjack_read_bulk_callback(struct urb *urb) | |||
324 | struct usb_serial_port *port = urb->context; | 324 | struct usb_serial_port *port = urb->context; |
325 | struct cyberjack_private *priv = usb_get_serial_port_data(port); | 325 | struct cyberjack_private *priv = usb_get_serial_port_data(port); |
326 | struct device *dev = &port->dev; | 326 | struct device *dev = &port->dev; |
327 | struct tty_struct *tty; | ||
328 | unsigned char *data = urb->transfer_buffer; | 327 | unsigned char *data = urb->transfer_buffer; |
329 | short todo; | 328 | short todo; |
330 | int result; | 329 | int result; |
@@ -337,16 +336,10 @@ static void cyberjack_read_bulk_callback(struct urb *urb) | |||
337 | return; | 336 | return; |
338 | } | 337 | } |
339 | 338 | ||
340 | tty = tty_port_tty_get(&port->port); | ||
341 | if (!tty) { | ||
342 | dev_dbg(dev, "%s - ignoring since device not open\n", __func__); | ||
343 | return; | ||
344 | } | ||
345 | if (urb->actual_length) { | 339 | if (urb->actual_length) { |
346 | tty_insert_flip_string(tty, data, urb->actual_length); | 340 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
347 | tty_flip_buffer_push(tty); | 341 | tty_flip_buffer_push(&port->port); |
348 | } | 342 | } |
349 | tty_kref_put(tty); | ||
350 | 343 | ||
351 | spin_lock(&priv->lock); | 344 | spin_lock(&priv->lock); |
352 | 345 | ||
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index fd8c35fd452e..8efa19d0e9fb 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1214,10 +1214,10 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1214 | spin_unlock_irqrestore(&priv->lock, flags); | 1214 | spin_unlock_irqrestore(&priv->lock, flags); |
1215 | 1215 | ||
1216 | /* process read if there is data other than line status */ | 1216 | /* process read if there is data other than line status */ |
1217 | if (tty && bytes > i) { | 1217 | if (bytes > i) { |
1218 | tty_insert_flip_string_fixed_flag(tty, data + i, | 1218 | tty_insert_flip_string_fixed_flag(&port->port, data + i, |
1219 | tty_flag, bytes - i); | 1219 | tty_flag, bytes - i); |
1220 | tty_flip_buffer_push(tty); | 1220 | tty_flip_buffer_push(&port->port); |
1221 | } | 1221 | } |
1222 | 1222 | ||
1223 | spin_lock_irqsave(&priv->lock, flags); | 1223 | spin_lock_irqsave(&priv->lock, flags); |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 45d4af62967f..ebe45fa0ed50 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -1399,9 +1399,7 @@ static void digi_read_bulk_callback(struct urb *urb) | |||
1399 | 1399 | ||
1400 | static int digi_read_inb_callback(struct urb *urb) | 1400 | static int digi_read_inb_callback(struct urb *urb) |
1401 | { | 1401 | { |
1402 | |||
1403 | struct usb_serial_port *port = urb->context; | 1402 | struct usb_serial_port *port = urb->context; |
1404 | struct tty_struct *tty; | ||
1405 | struct digi_port *priv = usb_get_serial_port_data(port); | 1403 | struct digi_port *priv = usb_get_serial_port_data(port); |
1406 | int opcode = ((unsigned char *)urb->transfer_buffer)[0]; | 1404 | int opcode = ((unsigned char *)urb->transfer_buffer)[0]; |
1407 | int len = ((unsigned char *)urb->transfer_buffer)[1]; | 1405 | int len = ((unsigned char *)urb->transfer_buffer)[1]; |
@@ -1425,7 +1423,6 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1425 | return -1; | 1423 | return -1; |
1426 | } | 1424 | } |
1427 | 1425 | ||
1428 | tty = tty_port_tty_get(&port->port); | ||
1429 | spin_lock(&priv->dp_port_lock); | 1426 | spin_lock(&priv->dp_port_lock); |
1430 | 1427 | ||
1431 | /* check for throttle; if set, do not resubmit read urb */ | 1428 | /* check for throttle; if set, do not resubmit read urb */ |
@@ -1435,13 +1432,13 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1435 | priv->dp_throttle_restart = 1; | 1432 | priv->dp_throttle_restart = 1; |
1436 | 1433 | ||
1437 | /* receive data */ | 1434 | /* receive data */ |
1438 | if (tty && opcode == DIGI_CMD_RECEIVE_DATA) { | 1435 | if (opcode == DIGI_CMD_RECEIVE_DATA) { |
1439 | /* get flag from port_status */ | 1436 | /* get flag from port_status */ |
1440 | flag = 0; | 1437 | flag = 0; |
1441 | 1438 | ||
1442 | /* overrun is special, not associated with a char */ | 1439 | /* overrun is special, not associated with a char */ |
1443 | if (port_status & DIGI_OVERRUN_ERROR) | 1440 | if (port_status & DIGI_OVERRUN_ERROR) |
1444 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 1441 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
1445 | 1442 | ||
1446 | /* break takes precedence over parity, */ | 1443 | /* break takes precedence over parity, */ |
1447 | /* which takes precedence over framing errors */ | 1444 | /* which takes precedence over framing errors */ |
@@ -1455,13 +1452,12 @@ static int digi_read_inb_callback(struct urb *urb) | |||
1455 | /* data length is len-1 (one byte of len is port_status) */ | 1452 | /* data length is len-1 (one byte of len is port_status) */ |
1456 | --len; | 1453 | --len; |
1457 | if (len > 0) { | 1454 | if (len > 0) { |
1458 | tty_insert_flip_string_fixed_flag(tty, data, flag, | 1455 | tty_insert_flip_string_fixed_flag(&port->port, data, |
1459 | len); | 1456 | flag, len); |
1460 | tty_flip_buffer_push(tty); | 1457 | tty_flip_buffer_push(&port->port); |
1461 | } | 1458 | } |
1462 | } | 1459 | } |
1463 | spin_unlock(&priv->dp_port_lock); | 1460 | spin_unlock(&priv->dp_port_lock); |
1464 | tty_kref_put(tty); | ||
1465 | 1461 | ||
1466 | if (opcode == DIGI_CMD_RECEIVE_DISABLE) | 1462 | if (opcode == DIGI_CMD_RECEIVE_DISABLE) |
1467 | dev_dbg(&port->dev, "%s: got RECEIVE_DISABLE\n", __func__); | 1463 | dev_dbg(&port->dev, "%s: got RECEIVE_DISABLE\n", __func__); |
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 6e4eb57d0177..b1b2dc64b50b 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c | |||
@@ -100,7 +100,6 @@ static void f81232_process_read_urb(struct urb *urb) | |||
100 | { | 100 | { |
101 | struct usb_serial_port *port = urb->context; | 101 | struct usb_serial_port *port = urb->context; |
102 | struct f81232_private *priv = usb_get_serial_port_data(port); | 102 | struct f81232_private *priv = usb_get_serial_port_data(port); |
103 | struct tty_struct *tty; | ||
104 | unsigned char *data = urb->transfer_buffer; | 103 | unsigned char *data = urb->transfer_buffer; |
105 | char tty_flag = TTY_NORMAL; | 104 | char tty_flag = TTY_NORMAL; |
106 | unsigned long flags; | 105 | unsigned long flags; |
@@ -117,10 +116,6 @@ static void f81232_process_read_urb(struct urb *urb) | |||
117 | if (!urb->actual_length) | 116 | if (!urb->actual_length) |
118 | return; | 117 | return; |
119 | 118 | ||
120 | tty = tty_port_tty_get(&port->port); | ||
121 | if (!tty) | ||
122 | return; | ||
123 | |||
124 | /* break takes precedence over parity, */ | 119 | /* break takes precedence over parity, */ |
125 | /* which takes precedence over framing errors */ | 120 | /* which takes precedence over framing errors */ |
126 | if (line_status & UART_BREAK_ERROR) | 121 | if (line_status & UART_BREAK_ERROR) |
@@ -133,19 +128,19 @@ static void f81232_process_read_urb(struct urb *urb) | |||
133 | 128 | ||
134 | /* overrun is special, not associated with a char */ | 129 | /* overrun is special, not associated with a char */ |
135 | if (line_status & UART_OVERRUN_ERROR) | 130 | if (line_status & UART_OVERRUN_ERROR) |
136 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 131 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
137 | 132 | ||
138 | if (port->port.console && port->sysrq) { | 133 | if (port->port.console && port->sysrq) { |
139 | for (i = 0; i < urb->actual_length; ++i) | 134 | for (i = 0; i < urb->actual_length; ++i) |
140 | if (!usb_serial_handle_sysrq_char(port, data[i])) | 135 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
141 | tty_insert_flip_char(tty, data[i], tty_flag); | 136 | tty_insert_flip_char(&port->port, data[i], |
137 | tty_flag); | ||
142 | } else { | 138 | } else { |
143 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 139 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
144 | urb->actual_length); | 140 | urb->actual_length); |
145 | } | 141 | } |
146 | 142 | ||
147 | tty_flip_buffer_push(tty); | 143 | tty_flip_buffer_push(&port->port); |
148 | tty_kref_put(tty); | ||
149 | } | 144 | } |
150 | 145 | ||
151 | static int set_control_lines(struct usb_device *dev, u8 value) | 146 | static int set_control_lines(struct usb_device *dev, u8 value) |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d07fccf3bab5..edd162df49ca 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1960,9 +1960,8 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, | |||
1960 | 1960 | ||
1961 | #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) | 1961 | #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) |
1962 | 1962 | ||
1963 | static int ftdi_process_packet(struct tty_struct *tty, | 1963 | static int ftdi_process_packet(struct usb_serial_port *port, |
1964 | struct usb_serial_port *port, struct ftdi_private *priv, | 1964 | struct ftdi_private *priv, char *packet, int len) |
1965 | char *packet, int len) | ||
1966 | { | 1965 | { |
1967 | int i; | 1966 | int i; |
1968 | char status; | 1967 | char status; |
@@ -2012,7 +2011,7 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
2012 | /* Overrun is special, not associated with a char */ | 2011 | /* Overrun is special, not associated with a char */ |
2013 | if (packet[1] & FTDI_RS_OE) { | 2012 | if (packet[1] & FTDI_RS_OE) { |
2014 | priv->icount.overrun++; | 2013 | priv->icount.overrun++; |
2015 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 2014 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
2016 | } | 2015 | } |
2017 | } | 2016 | } |
2018 | 2017 | ||
@@ -2031,10 +2030,10 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
2031 | if (port->port.console && port->sysrq) { | 2030 | if (port->port.console && port->sysrq) { |
2032 | for (i = 0; i < len; i++, ch++) { | 2031 | for (i = 0; i < len; i++, ch++) { |
2033 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 2032 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
2034 | tty_insert_flip_char(tty, *ch, flag); | 2033 | tty_insert_flip_char(&port->port, *ch, flag); |
2035 | } | 2034 | } |
2036 | } else { | 2035 | } else { |
2037 | tty_insert_flip_string_fixed_flag(tty, ch, flag, len); | 2036 | tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len); |
2038 | } | 2037 | } |
2039 | 2038 | ||
2040 | return len; | 2039 | return len; |
@@ -2043,25 +2042,19 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
2043 | static void ftdi_process_read_urb(struct urb *urb) | 2042 | static void ftdi_process_read_urb(struct urb *urb) |
2044 | { | 2043 | { |
2045 | struct usb_serial_port *port = urb->context; | 2044 | struct usb_serial_port *port = urb->context; |
2046 | struct tty_struct *tty; | ||
2047 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2045 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2048 | char *data = (char *)urb->transfer_buffer; | 2046 | char *data = (char *)urb->transfer_buffer; |
2049 | int i; | 2047 | int i; |
2050 | int len; | 2048 | int len; |
2051 | int count = 0; | 2049 | int count = 0; |
2052 | 2050 | ||
2053 | tty = tty_port_tty_get(&port->port); | ||
2054 | if (!tty) | ||
2055 | return; | ||
2056 | |||
2057 | for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { | 2051 | for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { |
2058 | len = min_t(int, urb->actual_length - i, priv->max_packet_size); | 2052 | len = min_t(int, urb->actual_length - i, priv->max_packet_size); |
2059 | count += ftdi_process_packet(tty, port, priv, &data[i], len); | 2053 | count += ftdi_process_packet(port, priv, &data[i], len); |
2060 | } | 2054 | } |
2061 | 2055 | ||
2062 | if (count) | 2056 | if (count) |
2063 | tty_flip_buffer_push(tty); | 2057 | tty_flip_buffer_push(&port->port); |
2064 | tty_kref_put(tty); | ||
2065 | } | 2058 | } |
2066 | 2059 | ||
2067 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state) | 2060 | static void ftdi_break_ctl(struct tty_struct *tty, int break_state) |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 203358d7e7bc..1a07b12ef341 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -252,14 +252,11 @@ static inline int isAbortTrfCmnd(const unsigned char *buf) | |||
252 | static void send_to_tty(struct usb_serial_port *port, | 252 | static void send_to_tty(struct usb_serial_port *port, |
253 | char *data, unsigned int actual_length) | 253 | char *data, unsigned int actual_length) |
254 | { | 254 | { |
255 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 255 | if (actual_length) { |
256 | |||
257 | if (tty && actual_length) { | ||
258 | usb_serial_debug_data(&port->dev, __func__, actual_length, data); | 256 | usb_serial_debug_data(&port->dev, __func__, actual_length, data); |
259 | tty_insert_flip_string(tty, data, actual_length); | 257 | tty_insert_flip_string(&port->port, data, actual_length); |
260 | tty_flip_buffer_push(tty); | 258 | tty_flip_buffer_push(&port->port); |
261 | } | 259 | } |
262 | tty_kref_put(tty); | ||
263 | } | 260 | } |
264 | 261 | ||
265 | 262 | ||
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 2ea70a631996..4c5c23f1cae5 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -313,30 +313,24 @@ EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs); | |||
313 | void usb_serial_generic_process_read_urb(struct urb *urb) | 313 | void usb_serial_generic_process_read_urb(struct urb *urb) |
314 | { | 314 | { |
315 | struct usb_serial_port *port = urb->context; | 315 | struct usb_serial_port *port = urb->context; |
316 | struct tty_struct *tty; | ||
317 | char *ch = (char *)urb->transfer_buffer; | 316 | char *ch = (char *)urb->transfer_buffer; |
318 | int i; | 317 | int i; |
319 | 318 | ||
320 | if (!urb->actual_length) | 319 | if (!urb->actual_length) |
321 | return; | 320 | return; |
322 | 321 | ||
323 | tty = tty_port_tty_get(&port->port); | ||
324 | if (!tty) | ||
325 | return; | ||
326 | |||
327 | /* The per character mucking around with sysrq path it too slow for | 322 | /* The per character mucking around with sysrq path it too slow for |
328 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases | 323 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases |
329 | where the USB serial is not a console anyway */ | 324 | where the USB serial is not a console anyway */ |
330 | if (!port->port.console || !port->sysrq) | 325 | if (!port->port.console || !port->sysrq) |
331 | tty_insert_flip_string(tty, ch, urb->actual_length); | 326 | tty_insert_flip_string(&port->port, ch, urb->actual_length); |
332 | else { | 327 | else { |
333 | for (i = 0; i < urb->actual_length; i++, ch++) { | 328 | for (i = 0; i < urb->actual_length; i++, ch++) { |
334 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 329 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
335 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 330 | tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); |
336 | } | 331 | } |
337 | } | 332 | } |
338 | tty_flip_buffer_push(tty); | 333 | tty_flip_buffer_push(&port->port); |
339 | tty_kref_put(tty); | ||
340 | } | 334 | } |
341 | EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb); | 335 | EXPORT_SYMBOL_GPL(usb_serial_generic_process_read_urb); |
342 | 336 | ||
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 7b770c7f8b11..b00e5cbf741f 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -232,8 +232,8 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, | |||
232 | unsigned char *buffer, __u16 bufferLength); | 232 | unsigned char *buffer, __u16 bufferLength); |
233 | static void process_rcvd_status(struct edgeport_serial *edge_serial, | 233 | static void process_rcvd_status(struct edgeport_serial *edge_serial, |
234 | __u8 byte2, __u8 byte3); | 234 | __u8 byte2, __u8 byte3); |
235 | static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | 235 | static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data, |
236 | unsigned char *data, int length); | 236 | int length); |
237 | static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr); | 237 | static void handle_new_msr(struct edgeport_port *edge_port, __u8 newMsr); |
238 | static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, | 238 | static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, |
239 | __u8 lsr, __u8 data); | 239 | __u8 lsr, __u8 data); |
@@ -1752,7 +1752,6 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, | |||
1752 | struct device *dev = &edge_serial->serial->dev->dev; | 1752 | struct device *dev = &edge_serial->serial->dev->dev; |
1753 | struct usb_serial_port *port; | 1753 | struct usb_serial_port *port; |
1754 | struct edgeport_port *edge_port; | 1754 | struct edgeport_port *edge_port; |
1755 | struct tty_struct *tty; | ||
1756 | __u16 lastBufferLength; | 1755 | __u16 lastBufferLength; |
1757 | __u16 rxLen; | 1756 | __u16 rxLen; |
1758 | 1757 | ||
@@ -1860,14 +1859,11 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial, | |||
1860 | edge_serial->rxPort]; | 1859 | edge_serial->rxPort]; |
1861 | edge_port = usb_get_serial_port_data(port); | 1860 | edge_port = usb_get_serial_port_data(port); |
1862 | if (edge_port->open) { | 1861 | if (edge_port->open) { |
1863 | tty = tty_port_tty_get( | 1862 | dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n", |
1864 | &edge_port->port->port); | 1863 | __func__, rxLen, |
1865 | if (tty) { | 1864 | edge_serial->rxPort); |
1866 | dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n", | 1865 | edge_tty_recv(edge_port->port, buffer, |
1867 | __func__, rxLen, edge_serial->rxPort); | 1866 | rxLen); |
1868 | edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen); | ||
1869 | tty_kref_put(tty); | ||
1870 | } | ||
1871 | edge_port->icount.rx += rxLen; | 1867 | edge_port->icount.rx += rxLen; |
1872 | } | 1868 | } |
1873 | buffer += rxLen; | 1869 | buffer += rxLen; |
@@ -2017,20 +2013,20 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, | |||
2017 | * edge_tty_recv | 2013 | * edge_tty_recv |
2018 | * this function passes data on to the tty flip buffer | 2014 | * this function passes data on to the tty flip buffer |
2019 | *****************************************************************************/ | 2015 | *****************************************************************************/ |
2020 | static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | 2016 | static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data, |
2021 | unsigned char *data, int length) | 2017 | int length) |
2022 | { | 2018 | { |
2023 | int cnt; | 2019 | int cnt; |
2024 | 2020 | ||
2025 | cnt = tty_insert_flip_string(tty, data, length); | 2021 | cnt = tty_insert_flip_string(&port->port, data, length); |
2026 | if (cnt < length) { | 2022 | if (cnt < length) { |
2027 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 2023 | dev_err(&port->dev, "%s - dropping data, %d bytes lost\n", |
2028 | __func__, length - cnt); | 2024 | __func__, length - cnt); |
2029 | } | 2025 | } |
2030 | data += cnt; | 2026 | data += cnt; |
2031 | length -= cnt; | 2027 | length -= cnt; |
2032 | 2028 | ||
2033 | tty_flip_buffer_push(tty); | 2029 | tty_flip_buffer_push(&port->port); |
2034 | } | 2030 | } |
2035 | 2031 | ||
2036 | 2032 | ||
@@ -2086,14 +2082,9 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, | |||
2086 | } | 2082 | } |
2087 | 2083 | ||
2088 | /* Place LSR data byte into Rx buffer */ | 2084 | /* Place LSR data byte into Rx buffer */ |
2089 | if (lsrData) { | 2085 | if (lsrData) |
2090 | struct tty_struct *tty = | 2086 | edge_tty_recv(edge_port->port, &data, 1); |
2091 | tty_port_tty_get(&edge_port->port->port); | 2087 | |
2092 | if (tty) { | ||
2093 | edge_tty_recv(&edge_port->port->dev, tty, &data, 1); | ||
2094 | tty_kref_put(tty); | ||
2095 | } | ||
2096 | } | ||
2097 | /* update input line counters */ | 2088 | /* update input line counters */ |
2098 | icount = &edge_port->icount; | 2089 | icount = &edge_port->icount; |
2099 | if (newLsr & LSR_BREAK) | 2090 | if (newLsr & LSR_BREAK) |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 641ab3da2d83..c23776679f70 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -201,8 +201,8 @@ static int closing_wait = EDGE_CLOSING_WAIT; | |||
201 | static bool ignore_cpu_rev; | 201 | static bool ignore_cpu_rev; |
202 | static int default_uart_mode; /* RS232 */ | 202 | static int default_uart_mode; /* RS232 */ |
203 | 203 | ||
204 | static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | 204 | static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data, |
205 | unsigned char *data, int length); | 205 | int length); |
206 | 206 | ||
207 | static void stop_read(struct edgeport_port *edge_port); | 207 | static void stop_read(struct edgeport_port *edge_port); |
208 | static int restart_read(struct edgeport_port *edge_port); | 208 | static int restart_read(struct edgeport_port *edge_port); |
@@ -1484,7 +1484,6 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, | |||
1484 | struct async_icount *icount; | 1484 | struct async_icount *icount; |
1485 | __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | | 1485 | __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR | |
1486 | LSR_FRM_ERR | LSR_BREAK)); | 1486 | LSR_FRM_ERR | LSR_BREAK)); |
1487 | struct tty_struct *tty; | ||
1488 | 1487 | ||
1489 | dev_dbg(&edge_port->port->dev, "%s - %02x\n", __func__, new_lsr); | 1488 | dev_dbg(&edge_port->port->dev, "%s - %02x\n", __func__, new_lsr); |
1490 | 1489 | ||
@@ -1498,13 +1497,8 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data, | |||
1498 | new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); | 1497 | new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK); |
1499 | 1498 | ||
1500 | /* Place LSR data byte into Rx buffer */ | 1499 | /* Place LSR data byte into Rx buffer */ |
1501 | if (lsr_data) { | 1500 | if (lsr_data) |
1502 | tty = tty_port_tty_get(&edge_port->port->port); | 1501 | edge_tty_recv(edge_port->port, &data, 1); |
1503 | if (tty) { | ||
1504 | edge_tty_recv(&edge_port->port->dev, tty, &data, 1); | ||
1505 | tty_kref_put(tty); | ||
1506 | } | ||
1507 | } | ||
1508 | 1502 | ||
1509 | /* update input line counters */ | 1503 | /* update input line counters */ |
1510 | icount = &edge_port->icount; | 1504 | icount = &edge_port->icount; |
@@ -1620,7 +1614,6 @@ static void edge_bulk_in_callback(struct urb *urb) | |||
1620 | struct edgeport_port *edge_port = urb->context; | 1614 | struct edgeport_port *edge_port = urb->context; |
1621 | struct device *dev = &edge_port->port->dev; | 1615 | struct device *dev = &edge_port->port->dev; |
1622 | unsigned char *data = urb->transfer_buffer; | 1616 | unsigned char *data = urb->transfer_buffer; |
1623 | struct tty_struct *tty; | ||
1624 | int retval = 0; | 1617 | int retval = 0; |
1625 | int port_number; | 1618 | int port_number; |
1626 | int status = urb->status; | 1619 | int status = urb->status; |
@@ -1659,17 +1652,16 @@ static void edge_bulk_in_callback(struct urb *urb) | |||
1659 | ++data; | 1652 | ++data; |
1660 | } | 1653 | } |
1661 | 1654 | ||
1662 | tty = tty_port_tty_get(&edge_port->port->port); | 1655 | if (urb->actual_length) { |
1663 | if (tty && urb->actual_length) { | ||
1664 | usb_serial_debug_data(dev, __func__, urb->actual_length, data); | 1656 | usb_serial_debug_data(dev, __func__, urb->actual_length, data); |
1665 | if (edge_port->close_pending) | 1657 | if (edge_port->close_pending) |
1666 | dev_dbg(dev, "%s - close pending, dropping data on the floor\n", | 1658 | dev_dbg(dev, "%s - close pending, dropping data on the floor\n", |
1667 | __func__); | 1659 | __func__); |
1668 | else | 1660 | else |
1669 | edge_tty_recv(dev, tty, data, urb->actual_length); | 1661 | edge_tty_recv(edge_port->port, data, |
1662 | urb->actual_length); | ||
1670 | edge_port->icount.rx += urb->actual_length; | 1663 | edge_port->icount.rx += urb->actual_length; |
1671 | } | 1664 | } |
1672 | tty_kref_put(tty); | ||
1673 | 1665 | ||
1674 | exit: | 1666 | exit: |
1675 | /* continue read unless stopped */ | 1667 | /* continue read unless stopped */ |
@@ -1684,16 +1676,16 @@ exit: | |||
1684 | dev_err(dev, "%s - usb_submit_urb failed with result %d\n", __func__, retval); | 1676 | dev_err(dev, "%s - usb_submit_urb failed with result %d\n", __func__, retval); |
1685 | } | 1677 | } |
1686 | 1678 | ||
1687 | static void edge_tty_recv(struct device *dev, struct tty_struct *tty, | 1679 | static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data, |
1688 | unsigned char *data, int length) | 1680 | int length) |
1689 | { | 1681 | { |
1690 | int queued; | 1682 | int queued; |
1691 | 1683 | ||
1692 | queued = tty_insert_flip_string(tty, data, length); | 1684 | queued = tty_insert_flip_string(&port->port, data, length); |
1693 | if (queued < length) | 1685 | if (queued < length) |
1694 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1686 | dev_err(&port->dev, "%s - dropping data, %d bytes lost\n", |
1695 | __func__, length - queued); | 1687 | __func__, length - queued); |
1696 | tty_flip_buffer_push(tty); | 1688 | tty_flip_buffer_push(&port->port); |
1697 | } | 1689 | } |
1698 | 1690 | ||
1699 | static void edge_bulk_out_callback(struct urb *urb) | 1691 | static void edge_bulk_out_callback(struct urb *urb) |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index e24e2d4f4c1b..716930ab1bb1 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -287,7 +287,6 @@ static void ir_process_read_urb(struct urb *urb) | |||
287 | { | 287 | { |
288 | struct usb_serial_port *port = urb->context; | 288 | struct usb_serial_port *port = urb->context; |
289 | unsigned char *data = urb->transfer_buffer; | 289 | unsigned char *data = urb->transfer_buffer; |
290 | struct tty_struct *tty; | ||
291 | 290 | ||
292 | if (!urb->actual_length) | 291 | if (!urb->actual_length) |
293 | return; | 292 | return; |
@@ -302,12 +301,8 @@ static void ir_process_read_urb(struct urb *urb) | |||
302 | if (urb->actual_length == 1) | 301 | if (urb->actual_length == 1) |
303 | return; | 302 | return; |
304 | 303 | ||
305 | tty = tty_port_tty_get(&port->port); | 304 | tty_insert_flip_string(&port->port, data + 1, urb->actual_length - 1); |
306 | if (!tty) | 305 | tty_flip_buffer_push(&port->port); |
307 | return; | ||
308 | tty_insert_flip_string(tty, data + 1, urb->actual_length - 1); | ||
309 | tty_flip_buffer_push(tty); | ||
310 | tty_kref_put(tty); | ||
311 | } | 306 | } |
312 | 307 | ||
313 | static void ir_set_termios_callback(struct urb *urb) | 308 | static void ir_set_termios_callback(struct urb *urb) |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 1e1fbed65ef2..ff77027160aa 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -581,7 +581,6 @@ static void read_buf_callback(struct urb *urb) | |||
581 | { | 581 | { |
582 | struct usb_serial_port *port = urb->context; | 582 | struct usb_serial_port *port = urb->context; |
583 | unsigned char *data = urb->transfer_buffer; | 583 | unsigned char *data = urb->transfer_buffer; |
584 | struct tty_struct *tty; | ||
585 | int status = urb->status; | 584 | int status = urb->status; |
586 | 585 | ||
587 | if (status) { | 586 | if (status) { |
@@ -592,14 +591,12 @@ static void read_buf_callback(struct urb *urb) | |||
592 | } | 591 | } |
593 | 592 | ||
594 | dev_dbg(&port->dev, "%s - %i chars to write\n", __func__, urb->actual_length); | 593 | dev_dbg(&port->dev, "%s - %i chars to write\n", __func__, urb->actual_length); |
595 | tty = tty_port_tty_get(&port->port); | ||
596 | if (data == NULL) | 594 | if (data == NULL) |
597 | dev_dbg(&port->dev, "%s - data is NULL !!!\n", __func__); | 595 | dev_dbg(&port->dev, "%s - data is NULL !!!\n", __func__); |
598 | if (tty && urb->actual_length && data) { | 596 | if (urb->actual_length && data) { |
599 | tty_insert_flip_string(tty, data, urb->actual_length); | 597 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
600 | tty_flip_buffer_push(tty); | 598 | tty_flip_buffer_push(&port->port); |
601 | } | 599 | } |
602 | tty_kref_put(tty); | ||
603 | iuu_led_activity_on(urb); | 600 | iuu_led_activity_on(urb); |
604 | } | 601 | } |
605 | 602 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 3d95637f3d68..1fd1935c8316 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -291,7 +291,6 @@ static void usa26_indat_callback(struct urb *urb) | |||
291 | int i, err; | 291 | int i, err; |
292 | int endpoint; | 292 | int endpoint; |
293 | struct usb_serial_port *port; | 293 | struct usb_serial_port *port; |
294 | struct tty_struct *tty; | ||
295 | unsigned char *data = urb->transfer_buffer; | 294 | unsigned char *data = urb->transfer_buffer; |
296 | int status = urb->status; | 295 | int status = urb->status; |
297 | 296 | ||
@@ -304,8 +303,7 @@ static void usa26_indat_callback(struct urb *urb) | |||
304 | } | 303 | } |
305 | 304 | ||
306 | port = urb->context; | 305 | port = urb->context; |
307 | tty = tty_port_tty_get(&port->port); | 306 | if (urb->actual_length) { |
308 | if (tty && urb->actual_length) { | ||
309 | /* 0x80 bit is error flag */ | 307 | /* 0x80 bit is error flag */ |
310 | if ((data[0] & 0x80) == 0) { | 308 | if ((data[0] & 0x80) == 0) { |
311 | /* no errors on individual bytes, only | 309 | /* no errors on individual bytes, only |
@@ -315,7 +313,7 @@ static void usa26_indat_callback(struct urb *urb) | |||
315 | else | 313 | else |
316 | err = 0; | 314 | err = 0; |
317 | for (i = 1; i < urb->actual_length ; ++i) | 315 | for (i = 1; i < urb->actual_length ; ++i) |
318 | tty_insert_flip_char(tty, data[i], err); | 316 | tty_insert_flip_char(&port->port, data[i], err); |
319 | } else { | 317 | } else { |
320 | /* some bytes had errors, every byte has status */ | 318 | /* some bytes had errors, every byte has status */ |
321 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); | 319 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); |
@@ -328,12 +326,12 @@ static void usa26_indat_callback(struct urb *urb) | |||
328 | if (stat & RXERROR_PARITY) | 326 | if (stat & RXERROR_PARITY) |
329 | flag |= TTY_PARITY; | 327 | flag |= TTY_PARITY; |
330 | /* XXX should handle break (0x10) */ | 328 | /* XXX should handle break (0x10) */ |
331 | tty_insert_flip_char(tty, data[i+1], flag); | 329 | tty_insert_flip_char(&port->port, data[i+1], |
330 | flag); | ||
332 | } | 331 | } |
333 | } | 332 | } |
334 | tty_flip_buffer_push(tty); | 333 | tty_flip_buffer_push(&port->port); |
335 | } | 334 | } |
336 | tty_kref_put(tty); | ||
337 | 335 | ||
338 | /* Resubmit urb so we continue receiving */ | 336 | /* Resubmit urb so we continue receiving */ |
339 | err = usb_submit_urb(urb, GFP_ATOMIC); | 337 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -446,7 +444,6 @@ static void usa28_indat_callback(struct urb *urb) | |||
446 | { | 444 | { |
447 | int err; | 445 | int err; |
448 | struct usb_serial_port *port; | 446 | struct usb_serial_port *port; |
449 | struct tty_struct *tty; | ||
450 | unsigned char *data; | 447 | unsigned char *data; |
451 | struct keyspan_port_private *p_priv; | 448 | struct keyspan_port_private *p_priv; |
452 | int status = urb->status; | 449 | int status = urb->status; |
@@ -469,12 +466,11 @@ static void usa28_indat_callback(struct urb *urb) | |||
469 | p_priv = usb_get_serial_port_data(port); | 466 | p_priv = usb_get_serial_port_data(port); |
470 | data = urb->transfer_buffer; | 467 | data = urb->transfer_buffer; |
471 | 468 | ||
472 | tty = tty_port_tty_get(&port->port); | 469 | if (urb->actual_length) { |
473 | if (tty && urb->actual_length) { | 470 | tty_insert_flip_string(&port->port, data, |
474 | tty_insert_flip_string(tty, data, urb->actual_length); | 471 | urb->actual_length); |
475 | tty_flip_buffer_push(tty); | 472 | tty_flip_buffer_push(&port->port); |
476 | } | 473 | } |
477 | tty_kref_put(tty); | ||
478 | 474 | ||
479 | /* Resubmit urb so we continue receiving */ | 475 | /* Resubmit urb so we continue receiving */ |
480 | err = usb_submit_urb(urb, GFP_ATOMIC); | 476 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -669,7 +665,6 @@ static void usa49_indat_callback(struct urb *urb) | |||
669 | int i, err; | 665 | int i, err; |
670 | int endpoint; | 666 | int endpoint; |
671 | struct usb_serial_port *port; | 667 | struct usb_serial_port *port; |
672 | struct tty_struct *tty; | ||
673 | unsigned char *data = urb->transfer_buffer; | 668 | unsigned char *data = urb->transfer_buffer; |
674 | int status = urb->status; | 669 | int status = urb->status; |
675 | 670 | ||
@@ -682,12 +677,11 @@ static void usa49_indat_callback(struct urb *urb) | |||
682 | } | 677 | } |
683 | 678 | ||
684 | port = urb->context; | 679 | port = urb->context; |
685 | tty = tty_port_tty_get(&port->port); | 680 | if (urb->actual_length) { |
686 | if (tty && urb->actual_length) { | ||
687 | /* 0x80 bit is error flag */ | 681 | /* 0x80 bit is error flag */ |
688 | if ((data[0] & 0x80) == 0) { | 682 | if ((data[0] & 0x80) == 0) { |
689 | /* no error on any byte */ | 683 | /* no error on any byte */ |
690 | tty_insert_flip_string(tty, data + 1, | 684 | tty_insert_flip_string(&port->port, data + 1, |
691 | urb->actual_length - 1); | 685 | urb->actual_length - 1); |
692 | } else { | 686 | } else { |
693 | /* some bytes had errors, every byte has status */ | 687 | /* some bytes had errors, every byte has status */ |
@@ -700,12 +694,12 @@ static void usa49_indat_callback(struct urb *urb) | |||
700 | if (stat & RXERROR_PARITY) | 694 | if (stat & RXERROR_PARITY) |
701 | flag |= TTY_PARITY; | 695 | flag |= TTY_PARITY; |
702 | /* XXX should handle break (0x10) */ | 696 | /* XXX should handle break (0x10) */ |
703 | tty_insert_flip_char(tty, data[i+1], flag); | 697 | tty_insert_flip_char(&port->port, data[i+1], |
698 | flag); | ||
704 | } | 699 | } |
705 | } | 700 | } |
706 | tty_flip_buffer_push(tty); | 701 | tty_flip_buffer_push(&port->port); |
707 | } | 702 | } |
708 | tty_kref_put(tty); | ||
709 | 703 | ||
710 | /* Resubmit urb so we continue receiving */ | 704 | /* Resubmit urb so we continue receiving */ |
711 | err = usb_submit_urb(urb, GFP_ATOMIC); | 705 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -718,7 +712,6 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
718 | int i, len, x, err; | 712 | int i, len, x, err; |
719 | struct usb_serial *serial; | 713 | struct usb_serial *serial; |
720 | struct usb_serial_port *port; | 714 | struct usb_serial_port *port; |
721 | struct tty_struct *tty; | ||
722 | unsigned char *data = urb->transfer_buffer; | 715 | unsigned char *data = urb->transfer_buffer; |
723 | int status = urb->status; | 716 | int status = urb->status; |
724 | 717 | ||
@@ -743,7 +736,6 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
743 | return; | 736 | return; |
744 | } | 737 | } |
745 | port = serial->port[data[i++]]; | 738 | port = serial->port[data[i++]]; |
746 | tty = tty_port_tty_get(&port->port); | ||
747 | len = data[i++]; | 739 | len = data[i++]; |
748 | 740 | ||
749 | /* 0x80 bit is error flag */ | 741 | /* 0x80 bit is error flag */ |
@@ -751,7 +743,8 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
751 | /* no error on any byte */ | 743 | /* no error on any byte */ |
752 | i++; | 744 | i++; |
753 | for (x = 1; x < len ; ++x) | 745 | for (x = 1; x < len ; ++x) |
754 | tty_insert_flip_char(tty, data[i++], 0); | 746 | tty_insert_flip_char(&port->port, |
747 | data[i++], 0); | ||
755 | } else { | 748 | } else { |
756 | /* | 749 | /* |
757 | * some bytes had errors, every byte has status | 750 | * some bytes had errors, every byte has status |
@@ -765,13 +758,12 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
765 | if (stat & RXERROR_PARITY) | 758 | if (stat & RXERROR_PARITY) |
766 | flag |= TTY_PARITY; | 759 | flag |= TTY_PARITY; |
767 | /* XXX should handle break (0x10) */ | 760 | /* XXX should handle break (0x10) */ |
768 | tty_insert_flip_char(tty, | 761 | tty_insert_flip_char(&port->port, |
769 | data[i+1], flag); | 762 | data[i+1], flag); |
770 | i += 2; | 763 | i += 2; |
771 | } | 764 | } |
772 | } | 765 | } |
773 | tty_flip_buffer_push(tty); | 766 | tty_flip_buffer_push(&port->port); |
774 | tty_kref_put(tty); | ||
775 | } | 767 | } |
776 | } | 768 | } |
777 | 769 | ||
@@ -792,7 +784,6 @@ static void usa90_indat_callback(struct urb *urb) | |||
792 | int endpoint; | 784 | int endpoint; |
793 | struct usb_serial_port *port; | 785 | struct usb_serial_port *port; |
794 | struct keyspan_port_private *p_priv; | 786 | struct keyspan_port_private *p_priv; |
795 | struct tty_struct *tty; | ||
796 | unsigned char *data = urb->transfer_buffer; | 787 | unsigned char *data = urb->transfer_buffer; |
797 | int status = urb->status; | 788 | int status = urb->status; |
798 | 789 | ||
@@ -808,12 +799,12 @@ static void usa90_indat_callback(struct urb *urb) | |||
808 | p_priv = usb_get_serial_port_data(port); | 799 | p_priv = usb_get_serial_port_data(port); |
809 | 800 | ||
810 | if (urb->actual_length) { | 801 | if (urb->actual_length) { |
811 | tty = tty_port_tty_get(&port->port); | ||
812 | /* if current mode is DMA, looks like usa28 format | 802 | /* if current mode is DMA, looks like usa28 format |
813 | otherwise looks like usa26 data format */ | 803 | otherwise looks like usa26 data format */ |
814 | 804 | ||
815 | if (p_priv->baud > 57600) | 805 | if (p_priv->baud > 57600) |
816 | tty_insert_flip_string(tty, data, urb->actual_length); | 806 | tty_insert_flip_string(&port->port, data, |
807 | urb->actual_length); | ||
817 | else { | 808 | else { |
818 | /* 0x80 bit is error flag */ | 809 | /* 0x80 bit is error flag */ |
819 | if ((data[0] & 0x80) == 0) { | 810 | if ((data[0] & 0x80) == 0) { |
@@ -824,8 +815,8 @@ static void usa90_indat_callback(struct urb *urb) | |||
824 | else | 815 | else |
825 | err = 0; | 816 | err = 0; |
826 | for (i = 1; i < urb->actual_length ; ++i) | 817 | for (i = 1; i < urb->actual_length ; ++i) |
827 | tty_insert_flip_char(tty, data[i], | 818 | tty_insert_flip_char(&port->port, |
828 | err); | 819 | data[i], err); |
829 | } else { | 820 | } else { |
830 | /* some bytes had errors, every byte has status */ | 821 | /* some bytes had errors, every byte has status */ |
831 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); | 822 | dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); |
@@ -838,13 +829,12 @@ static void usa90_indat_callback(struct urb *urb) | |||
838 | if (stat & RXERROR_PARITY) | 829 | if (stat & RXERROR_PARITY) |
839 | flag |= TTY_PARITY; | 830 | flag |= TTY_PARITY; |
840 | /* XXX should handle break (0x10) */ | 831 | /* XXX should handle break (0x10) */ |
841 | tty_insert_flip_char(tty, data[i+1], | 832 | tty_insert_flip_char(&port->port, |
842 | flag); | 833 | data[i+1], flag); |
843 | } | 834 | } |
844 | } | 835 | } |
845 | } | 836 | } |
846 | tty_flip_buffer_push(tty); | 837 | tty_flip_buffer_push(&port->port); |
847 | tty_kref_put(tty); | ||
848 | } | 838 | } |
849 | 839 | ||
850 | /* Resubmit urb so we continue receiving */ | 840 | /* Resubmit urb so we continue receiving */ |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 41b01092af07..3b17d5d13dc8 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -138,7 +138,6 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work) | |||
138 | static void keyspan_pda_rx_interrupt(struct urb *urb) | 138 | static void keyspan_pda_rx_interrupt(struct urb *urb) |
139 | { | 139 | { |
140 | struct usb_serial_port *port = urb->context; | 140 | struct usb_serial_port *port = urb->context; |
141 | struct tty_struct *tty; | ||
142 | unsigned char *data = urb->transfer_buffer; | 141 | unsigned char *data = urb->transfer_buffer; |
143 | int retval; | 142 | int retval; |
144 | int status = urb->status; | 143 | int status = urb->status; |
@@ -163,14 +162,12 @@ static void keyspan_pda_rx_interrupt(struct urb *urb) | |||
163 | /* see if the message is data or a status interrupt */ | 162 | /* see if the message is data or a status interrupt */ |
164 | switch (data[0]) { | 163 | switch (data[0]) { |
165 | case 0: | 164 | case 0: |
166 | tty = tty_port_tty_get(&port->port); | ||
167 | /* rest of message is rx data */ | 165 | /* rest of message is rx data */ |
168 | if (tty && urb->actual_length) { | 166 | if (urb->actual_length) { |
169 | tty_insert_flip_string(tty, data + 1, | 167 | tty_insert_flip_string(&port->port, data + 1, |
170 | urb->actual_length - 1); | 168 | urb->actual_length - 1); |
171 | tty_flip_buffer_push(tty); | 169 | tty_flip_buffer_push(&port->port); |
172 | } | 170 | } |
173 | tty_kref_put(tty); | ||
174 | break; | 171 | break; |
175 | case 1: | 172 | case 1: |
176 | /* status interrupt */ | 173 | /* status interrupt */ |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index fc9e14a1e9b3..769d910ae0a5 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -389,7 +389,6 @@ static void klsi_105_process_read_urb(struct urb *urb) | |||
389 | { | 389 | { |
390 | struct usb_serial_port *port = urb->context; | 390 | struct usb_serial_port *port = urb->context; |
391 | unsigned char *data = urb->transfer_buffer; | 391 | unsigned char *data = urb->transfer_buffer; |
392 | struct tty_struct *tty; | ||
393 | unsigned len; | 392 | unsigned len; |
394 | 393 | ||
395 | /* empty urbs seem to happen, we ignore them */ | 394 | /* empty urbs seem to happen, we ignore them */ |
@@ -401,19 +400,14 @@ static void klsi_105_process_read_urb(struct urb *urb) | |||
401 | return; | 400 | return; |
402 | } | 401 | } |
403 | 402 | ||
404 | tty = tty_port_tty_get(&port->port); | ||
405 | if (!tty) | ||
406 | return; | ||
407 | |||
408 | len = get_unaligned_le16(data); | 403 | len = get_unaligned_le16(data); |
409 | if (len > urb->actual_length - KLSI_HDR_LEN) { | 404 | if (len > urb->actual_length - KLSI_HDR_LEN) { |
410 | dev_dbg(&port->dev, "%s - packet length mismatch\n", __func__); | 405 | dev_dbg(&port->dev, "%s - packet length mismatch\n", __func__); |
411 | len = urb->actual_length - KLSI_HDR_LEN; | 406 | len = urb->actual_length - KLSI_HDR_LEN; |
412 | } | 407 | } |
413 | 408 | ||
414 | tty_insert_flip_string(tty, data + KLSI_HDR_LEN, len); | 409 | tty_insert_flip_string(&port->port, data + KLSI_HDR_LEN, len); |
415 | tty_flip_buffer_push(tty); | 410 | tty_flip_buffer_push(&port->port); |
416 | tty_kref_put(tty); | ||
417 | } | 411 | } |
418 | 412 | ||
419 | static void klsi_105_set_termios(struct tty_struct *tty, | 413 | static void klsi_105_set_termios(struct tty_struct *tty, |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index b747ba615d0b..903d938e174b 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -324,7 +324,6 @@ static void kobil_read_int_callback(struct urb *urb) | |||
324 | { | 324 | { |
325 | int result; | 325 | int result; |
326 | struct usb_serial_port *port = urb->context; | 326 | struct usb_serial_port *port = urb->context; |
327 | struct tty_struct *tty; | ||
328 | unsigned char *data = urb->transfer_buffer; | 327 | unsigned char *data = urb->transfer_buffer; |
329 | int status = urb->status; | 328 | int status = urb->status; |
330 | 329 | ||
@@ -333,8 +332,7 @@ static void kobil_read_int_callback(struct urb *urb) | |||
333 | return; | 332 | return; |
334 | } | 333 | } |
335 | 334 | ||
336 | tty = tty_port_tty_get(&port->port); | 335 | if (urb->actual_length) { |
337 | if (tty && urb->actual_length) { | ||
338 | 336 | ||
339 | /* BEGIN DEBUG */ | 337 | /* BEGIN DEBUG */ |
340 | /* | 338 | /* |
@@ -353,10 +351,9 @@ static void kobil_read_int_callback(struct urb *urb) | |||
353 | */ | 351 | */ |
354 | /* END DEBUG */ | 352 | /* END DEBUG */ |
355 | 353 | ||
356 | tty_insert_flip_string(tty, data, urb->actual_length); | 354 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
357 | tty_flip_buffer_push(tty); | 355 | tty_flip_buffer_push(&port->port); |
358 | } | 356 | } |
359 | tty_kref_put(tty); | ||
360 | 357 | ||
361 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 358 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
362 | dev_dbg(&port->dev, "%s - Send read URB returns: %i\n", __func__, result); | 359 | dev_dbg(&port->dev, "%s - Send read URB returns: %i\n", __func__, result); |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index d9c86516fed4..a64d420f687b 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -527,7 +527,6 @@ static void mct_u232_read_int_callback(struct urb *urb) | |||
527 | { | 527 | { |
528 | struct usb_serial_port *port = urb->context; | 528 | struct usb_serial_port *port = urb->context; |
529 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 529 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
530 | struct tty_struct *tty; | ||
531 | unsigned char *data = urb->transfer_buffer; | 530 | unsigned char *data = urb->transfer_buffer; |
532 | int retval; | 531 | int retval; |
533 | int status = urb->status; | 532 | int status = urb->status; |
@@ -557,13 +556,9 @@ static void mct_u232_read_int_callback(struct urb *urb) | |||
557 | */ | 556 | */ |
558 | if (urb->transfer_buffer_length > 2) { | 557 | if (urb->transfer_buffer_length > 2) { |
559 | if (urb->actual_length) { | 558 | if (urb->actual_length) { |
560 | tty = tty_port_tty_get(&port->port); | 559 | tty_insert_flip_string(&port->port, data, |
561 | if (tty) { | 560 | urb->actual_length); |
562 | tty_insert_flip_string(tty, data, | 561 | tty_flip_buffer_push(&port->port); |
563 | urb->actual_length); | ||
564 | tty_flip_buffer_push(tty); | ||
565 | } | ||
566 | tty_kref_put(tty); | ||
567 | } | 562 | } |
568 | goto exit; | 563 | goto exit; |
569 | } | 564 | } |
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 3d258448c29a..bf3c7a23553e 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c | |||
@@ -95,7 +95,6 @@ static void metrousb_read_int_callback(struct urb *urb) | |||
95 | { | 95 | { |
96 | struct usb_serial_port *port = urb->context; | 96 | struct usb_serial_port *port = urb->context; |
97 | struct metrousb_private *metro_priv = usb_get_serial_port_data(port); | 97 | struct metrousb_private *metro_priv = usb_get_serial_port_data(port); |
98 | struct tty_struct *tty; | ||
99 | unsigned char *data = urb->transfer_buffer; | 98 | unsigned char *data = urb->transfer_buffer; |
100 | int throttled = 0; | 99 | int throttled = 0; |
101 | int result = 0; | 100 | int result = 0; |
@@ -124,15 +123,13 @@ static void metrousb_read_int_callback(struct urb *urb) | |||
124 | 123 | ||
125 | 124 | ||
126 | /* Set the data read from the usb port into the serial port buffer. */ | 125 | /* Set the data read from the usb port into the serial port buffer. */ |
127 | tty = tty_port_tty_get(&port->port); | 126 | if (urb->actual_length) { |
128 | if (tty && urb->actual_length) { | ||
129 | /* Loop through the data copying each byte to the tty layer. */ | 127 | /* Loop through the data copying each byte to the tty layer. */ |
130 | tty_insert_flip_string(tty, data, urb->actual_length); | 128 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
131 | 129 | ||
132 | /* Force the data to the tty layer. */ | 130 | /* Force the data to the tty layer. */ |
133 | tty_flip_buffer_push(tty); | 131 | tty_flip_buffer_push(&port->port); |
134 | } | 132 | } |
135 | tty_kref_put(tty); | ||
136 | 133 | ||
137 | /* Set any port variables. */ | 134 | /* Set any port variables. */ |
138 | spin_lock_irqsave(&metro_priv->lock, flags); | 135 | spin_lock_irqsave(&metro_priv->lock, flags); |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index f57a6b1fe787..e0ebec3b5d6a 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -899,7 +899,6 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
899 | int retval; | 899 | int retval; |
900 | unsigned char *data ; | 900 | unsigned char *data ; |
901 | struct usb_serial_port *port; | 901 | struct usb_serial_port *port; |
902 | struct tty_struct *tty; | ||
903 | int status = urb->status; | 902 | int status = urb->status; |
904 | 903 | ||
905 | if (status) { | 904 | if (status) { |
@@ -913,12 +912,10 @@ static void mos7720_bulk_in_callback(struct urb *urb) | |||
913 | 912 | ||
914 | data = urb->transfer_buffer; | 913 | data = urb->transfer_buffer; |
915 | 914 | ||
916 | tty = tty_port_tty_get(&port->port); | 915 | if (urb->actual_length) { |
917 | if (tty && urb->actual_length) { | 916 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
918 | tty_insert_flip_string(tty, data, urb->actual_length); | 917 | tty_flip_buffer_push(&port->port); |
919 | tty_flip_buffer_push(tty); | ||
920 | } | 918 | } |
921 | tty_kref_put(tty); | ||
922 | 919 | ||
923 | if (port->read_urb->status != -EINPROGRESS) { | 920 | if (port->read_urb->status != -EINPROGRESS) { |
924 | retval = usb_submit_urb(port->read_urb, GFP_ATOMIC); | 921 | retval = usb_submit_urb(port->read_urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 66d9e088d9d9..809fb329eca5 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -744,7 +744,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
744 | struct usb_serial *serial; | 744 | struct usb_serial *serial; |
745 | struct usb_serial_port *port; | 745 | struct usb_serial_port *port; |
746 | struct moschip_port *mos7840_port; | 746 | struct moschip_port *mos7840_port; |
747 | struct tty_struct *tty; | ||
748 | int status = urb->status; | 747 | int status = urb->status; |
749 | 748 | ||
750 | mos7840_port = urb->context; | 749 | mos7840_port = urb->context; |
@@ -773,12 +772,9 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
773 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); | 772 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); |
774 | 773 | ||
775 | if (urb->actual_length) { | 774 | if (urb->actual_length) { |
776 | tty = tty_port_tty_get(&mos7840_port->port->port); | 775 | struct tty_port *tport = &mos7840_port->port->port; |
777 | if (tty) { | 776 | tty_insert_flip_string(tport, data, urb->actual_length); |
778 | tty_insert_flip_string(tty, data, urb->actual_length); | 777 | tty_flip_buffer_push(tport); |
779 | tty_flip_buffer_push(tty); | ||
780 | tty_kref_put(tty); | ||
781 | } | ||
782 | mos7840_port->icount.rx += urb->actual_length; | 778 | mos7840_port->icount.rx += urb->actual_length; |
783 | smp_wmb(); | 779 | smp_wmb(); |
784 | dev_dbg(&port->dev, "mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx); | 780 | dev_dbg(&port->dev, "mos7840_port->icount.rx is %d:\n", mos7840_port->icount.rx); |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 1566f8f500ae..38725fc8c2c8 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -32,7 +32,6 @@ static void navman_read_int_callback(struct urb *urb) | |||
32 | { | 32 | { |
33 | struct usb_serial_port *port = urb->context; | 33 | struct usb_serial_port *port = urb->context; |
34 | unsigned char *data = urb->transfer_buffer; | 34 | unsigned char *data = urb->transfer_buffer; |
35 | struct tty_struct *tty; | ||
36 | int status = urb->status; | 35 | int status = urb->status; |
37 | int result; | 36 | int result; |
38 | 37 | ||
@@ -55,12 +54,10 @@ static void navman_read_int_callback(struct urb *urb) | |||
55 | 54 | ||
56 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); | 55 | usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); |
57 | 56 | ||
58 | tty = tty_port_tty_get(&port->port); | 57 | if (urb->actual_length) { |
59 | if (tty && urb->actual_length) { | 58 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
60 | tty_insert_flip_string(tty, data, urb->actual_length); | 59 | tty_flip_buffer_push(&port->port); |
61 | tty_flip_buffer_push(tty); | ||
62 | } | 60 | } |
63 | tty_kref_put(tty); | ||
64 | 61 | ||
65 | exit: | 62 | exit: |
66 | result = usb_submit_urb(urb, GFP_ATOMIC); | 63 | result = usb_submit_urb(urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 7818af931a48..1e1cafe287e4 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -174,13 +174,9 @@ static void omninet_read_bulk_callback(struct urb *urb) | |||
174 | } | 174 | } |
175 | 175 | ||
176 | if (urb->actual_length && header->oh_len) { | 176 | if (urb->actual_length && header->oh_len) { |
177 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 177 | tty_insert_flip_string(&port->port, data + OMNINET_DATAOFFSET, |
178 | if (tty) { | 178 | header->oh_len); |
179 | tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET, | 179 | tty_flip_buffer_push(&port->port); |
180 | header->oh_len); | ||
181 | tty_flip_buffer_push(tty); | ||
182 | tty_kref_put(tty); | ||
183 | } | ||
184 | } | 180 | } |
185 | 181 | ||
186 | /* Continue trying to always read */ | 182 | /* Continue trying to always read */ |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index c6bfb83efb1e..e13e1a4d3e1e 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -51,15 +51,8 @@ struct opticon_private { | |||
51 | static void opticon_process_data_packet(struct usb_serial_port *port, | 51 | static void opticon_process_data_packet(struct usb_serial_port *port, |
52 | const unsigned char *buf, size_t len) | 52 | const unsigned char *buf, size_t len) |
53 | { | 53 | { |
54 | struct tty_struct *tty; | 54 | tty_insert_flip_string(&port->port, buf, len); |
55 | 55 | tty_flip_buffer_push(&port->port); | |
56 | tty = tty_port_tty_get(&port->port); | ||
57 | if (!tty) | ||
58 | return; | ||
59 | |||
60 | tty_insert_flip_string(tty, buf, len); | ||
61 | tty_flip_buffer_push(tty); | ||
62 | tty_kref_put(tty); | ||
63 | } | 56 | } |
64 | 57 | ||
65 | static void opticon_process_status_packet(struct usb_serial_port *port, | 58 | static void opticon_process_status_packet(struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index d217fd6ee43f..a958fd41b5b3 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -820,7 +820,6 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
820 | { | 820 | { |
821 | struct usb_serial_port *port = urb->context; | 821 | struct usb_serial_port *port = urb->context; |
822 | struct oti6858_private *priv = usb_get_serial_port_data(port); | 822 | struct oti6858_private *priv = usb_get_serial_port_data(port); |
823 | struct tty_struct *tty; | ||
824 | unsigned char *data = urb->transfer_buffer; | 823 | unsigned char *data = urb->transfer_buffer; |
825 | unsigned long flags; | 824 | unsigned long flags; |
826 | int status = urb->status; | 825 | int status = urb->status; |
@@ -835,12 +834,10 @@ static void oti6858_read_bulk_callback(struct urb *urb) | |||
835 | return; | 834 | return; |
836 | } | 835 | } |
837 | 836 | ||
838 | tty = tty_port_tty_get(&port->port); | 837 | if (urb->actual_length > 0) { |
839 | if (tty != NULL && urb->actual_length > 0) { | 838 | tty_insert_flip_string(&port->port, data, urb->actual_length); |
840 | tty_insert_flip_string(tty, data, urb->actual_length); | 839 | tty_flip_buffer_push(&port->port); |
841 | tty_flip_buffer_push(tty); | ||
842 | } | 840 | } |
843 | tty_kref_put(tty); | ||
844 | 841 | ||
845 | /* schedule the interrupt urb */ | 842 | /* schedule the interrupt urb */ |
846 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); | 843 | result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 600241901361..54adc9125e5c 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -772,7 +772,6 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
772 | { | 772 | { |
773 | struct usb_serial_port *port = urb->context; | 773 | struct usb_serial_port *port = urb->context; |
774 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 774 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
775 | struct tty_struct *tty; | ||
776 | unsigned char *data = urb->transfer_buffer; | 775 | unsigned char *data = urb->transfer_buffer; |
777 | char tty_flag = TTY_NORMAL; | 776 | char tty_flag = TTY_NORMAL; |
778 | unsigned long flags; | 777 | unsigned long flags; |
@@ -789,10 +788,6 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
789 | if (!urb->actual_length) | 788 | if (!urb->actual_length) |
790 | return; | 789 | return; |
791 | 790 | ||
792 | tty = tty_port_tty_get(&port->port); | ||
793 | if (!tty) | ||
794 | return; | ||
795 | |||
796 | /* break takes precedence over parity, */ | 791 | /* break takes precedence over parity, */ |
797 | /* which takes precedence over framing errors */ | 792 | /* which takes precedence over framing errors */ |
798 | if (line_status & UART_BREAK_ERROR) | 793 | if (line_status & UART_BREAK_ERROR) |
@@ -805,19 +800,19 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
805 | 800 | ||
806 | /* overrun is special, not associated with a char */ | 801 | /* overrun is special, not associated with a char */ |
807 | if (line_status & UART_OVERRUN_ERROR) | 802 | if (line_status & UART_OVERRUN_ERROR) |
808 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 803 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
809 | 804 | ||
810 | if (port->port.console && port->sysrq) { | 805 | if (port->port.console && port->sysrq) { |
811 | for (i = 0; i < urb->actual_length; ++i) | 806 | for (i = 0; i < urb->actual_length; ++i) |
812 | if (!usb_serial_handle_sysrq_char(port, data[i])) | 807 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
813 | tty_insert_flip_char(tty, data[i], tty_flag); | 808 | tty_insert_flip_char(&port->port, data[i], |
809 | tty_flag); | ||
814 | } else { | 810 | } else { |
815 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 811 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
816 | urb->actual_length); | 812 | urb->actual_length); |
817 | } | 813 | } |
818 | 814 | ||
819 | tty_flip_buffer_push(tty); | 815 | tty_flip_buffer_push(&port->port); |
820 | tty_kref_put(tty); | ||
821 | } | 816 | } |
822 | 817 | ||
823 | /* All of the device info needed for the PL2303 SIO serial converter */ | 818 | /* All of the device info needed for the PL2303 SIO serial converter */ |
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index a8d5110d4cc5..00e6c9bac8a3 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
@@ -609,7 +609,6 @@ void qt2_process_read_urb(struct urb *urb) | |||
609 | struct qt2_serial_private *serial_priv; | 609 | struct qt2_serial_private *serial_priv; |
610 | struct usb_serial_port *port; | 610 | struct usb_serial_port *port; |
611 | struct qt2_port_private *port_priv; | 611 | struct qt2_port_private *port_priv; |
612 | struct tty_struct *tty; | ||
613 | bool escapeflag; | 612 | bool escapeflag; |
614 | unsigned char *ch; | 613 | unsigned char *ch; |
615 | int i; | 614 | int i; |
@@ -620,15 +619,11 @@ void qt2_process_read_urb(struct urb *urb) | |||
620 | return; | 619 | return; |
621 | 620 | ||
622 | ch = urb->transfer_buffer; | 621 | ch = urb->transfer_buffer; |
623 | tty = NULL; | ||
624 | serial = urb->context; | 622 | serial = urb->context; |
625 | serial_priv = usb_get_serial_data(serial); | 623 | serial_priv = usb_get_serial_data(serial); |
626 | port = serial->port[serial_priv->current_port]; | 624 | port = serial->port[serial_priv->current_port]; |
627 | port_priv = usb_get_serial_port_data(port); | 625 | port_priv = usb_get_serial_port_data(port); |
628 | 626 | ||
629 | if (port_priv->is_open) | ||
630 | tty = tty_port_tty_get(&port->port); | ||
631 | |||
632 | for (i = 0; i < urb->actual_length; i++) { | 627 | for (i = 0; i < urb->actual_length; i++) { |
633 | ch = (unsigned char *)urb->transfer_buffer + i; | 628 | ch = (unsigned char *)urb->transfer_buffer + i; |
634 | if ((i <= (len - 3)) && | 629 | if ((i <= (len - 3)) && |
@@ -666,10 +661,7 @@ void qt2_process_read_urb(struct urb *urb) | |||
666 | __func__); | 661 | __func__); |
667 | break; | 662 | break; |
668 | } | 663 | } |
669 | if (tty) { | 664 | tty_flip_buffer_push(&port->port); |
670 | tty_flip_buffer_push(tty); | ||
671 | tty_kref_put(tty); | ||
672 | } | ||
673 | 665 | ||
674 | newport = *(ch + 3); | 666 | newport = *(ch + 3); |
675 | 667 | ||
@@ -683,10 +675,6 @@ void qt2_process_read_urb(struct urb *urb) | |||
683 | serial_priv->current_port = newport; | 675 | serial_priv->current_port = newport; |
684 | port = serial->port[serial_priv->current_port]; | 676 | port = serial->port[serial_priv->current_port]; |
685 | port_priv = usb_get_serial_port_data(port); | 677 | port_priv = usb_get_serial_port_data(port); |
686 | if (port_priv->is_open) | ||
687 | tty = tty_port_tty_get(&port->port); | ||
688 | else | ||
689 | tty = NULL; | ||
690 | i += 3; | 678 | i += 3; |
691 | escapeflag = true; | 679 | escapeflag = true; |
692 | break; | 680 | break; |
@@ -697,8 +685,8 @@ void qt2_process_read_urb(struct urb *urb) | |||
697 | escapeflag = true; | 685 | escapeflag = true; |
698 | break; | 686 | break; |
699 | case QT2_CONTROL_ESCAPE: | 687 | case QT2_CONTROL_ESCAPE: |
700 | tty_buffer_request_room(tty, 2); | 688 | tty_buffer_request_room(&port->port, 2); |
701 | tty_insert_flip_string(tty, ch, 2); | 689 | tty_insert_flip_string(&port->port, ch, 2); |
702 | i += 2; | 690 | i += 2; |
703 | escapeflag = true; | 691 | escapeflag = true; |
704 | break; | 692 | break; |
@@ -712,16 +700,11 @@ void qt2_process_read_urb(struct urb *urb) | |||
712 | continue; | 700 | continue; |
713 | } | 701 | } |
714 | 702 | ||
715 | if (tty) { | 703 | tty_buffer_request_room(&port->port, 1); |
716 | tty_buffer_request_room(tty, 1); | 704 | tty_insert_flip_string(&port->port, ch, 1); |
717 | tty_insert_flip_string(tty, ch, 1); | ||
718 | } | ||
719 | } | 705 | } |
720 | 706 | ||
721 | if (tty) { | 707 | tty_flip_buffer_push(&port->port); |
722 | tty_flip_buffer_push(tty); | ||
723 | tty_kref_put(tty); | ||
724 | } | ||
725 | } | 708 | } |
726 | 709 | ||
727 | static void qt2_write_bulk_callback(struct urb *urb) | 710 | static void qt2_write_bulk_callback(struct urb *urb) |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index c949ce6ef0c6..21cd7bf2a8cc 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -207,38 +207,31 @@ static void safe_process_read_urb(struct urb *urb) | |||
207 | unsigned char *data = urb->transfer_buffer; | 207 | unsigned char *data = urb->transfer_buffer; |
208 | unsigned char length = urb->actual_length; | 208 | unsigned char length = urb->actual_length; |
209 | int actual_length; | 209 | int actual_length; |
210 | struct tty_struct *tty; | ||
211 | __u16 fcs; | 210 | __u16 fcs; |
212 | 211 | ||
213 | if (!length) | 212 | if (!length) |
214 | return; | 213 | return; |
215 | 214 | ||
216 | tty = tty_port_tty_get(&port->port); | ||
217 | if (!tty) | ||
218 | return; | ||
219 | |||
220 | if (!safe) | 215 | if (!safe) |
221 | goto out; | 216 | goto out; |
222 | 217 | ||
223 | fcs = fcs_compute10(data, length, CRC10_INITFCS); | 218 | fcs = fcs_compute10(data, length, CRC10_INITFCS); |
224 | if (fcs) { | 219 | if (fcs) { |
225 | dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); | 220 | dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs); |
226 | goto err; | 221 | return; |
227 | } | 222 | } |
228 | 223 | ||
229 | actual_length = data[length - 2] >> 2; | 224 | actual_length = data[length - 2] >> 2; |
230 | if (actual_length > (length - 2)) { | 225 | if (actual_length > (length - 2)) { |
231 | dev_err(&port->dev, "%s - inconsistent lengths %d:%d\n", | 226 | dev_err(&port->dev, "%s - inconsistent lengths %d:%d\n", |
232 | __func__, actual_length, length); | 227 | __func__, actual_length, length); |
233 | goto err; | 228 | return; |
234 | } | 229 | } |
235 | dev_info(&urb->dev->dev, "%s - actual: %d\n", __func__, actual_length); | 230 | dev_info(&urb->dev->dev, "%s - actual: %d\n", __func__, actual_length); |
236 | length = actual_length; | 231 | length = actual_length; |
237 | out: | 232 | out: |
238 | tty_insert_flip_string(tty, data, length); | 233 | tty_insert_flip_string(&port->port, data, length); |
239 | tty_flip_buffer_push(tty); | 234 | tty_flip_buffer_push(&port->port); |
240 | err: | ||
241 | tty_kref_put(tty); | ||
242 | } | 235 | } |
243 | 236 | ||
244 | static int safe_prepare_write_buffer(struct usb_serial_port *port, | 237 | static int safe_prepare_write_buffer(struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index d4426c038c32..c13f6e747748 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -569,7 +569,6 @@ static void sierra_indat_callback(struct urb *urb) | |||
569 | int err; | 569 | int err; |
570 | int endpoint; | 570 | int endpoint; |
571 | struct usb_serial_port *port; | 571 | struct usb_serial_port *port; |
572 | struct tty_struct *tty; | ||
573 | unsigned char *data = urb->transfer_buffer; | 572 | unsigned char *data = urb->transfer_buffer; |
574 | int status = urb->status; | 573 | int status = urb->status; |
575 | 574 | ||
@@ -581,16 +580,12 @@ static void sierra_indat_callback(struct urb *urb) | |||
581 | " endpoint %02x\n", __func__, status, endpoint); | 580 | " endpoint %02x\n", __func__, status, endpoint); |
582 | } else { | 581 | } else { |
583 | if (urb->actual_length) { | 582 | if (urb->actual_length) { |
584 | tty = tty_port_tty_get(&port->port); | 583 | tty_insert_flip_string(&port->port, data, |
585 | if (tty) { | 584 | urb->actual_length); |
586 | tty_insert_flip_string(tty, data, | 585 | tty_flip_buffer_push(&port->port); |
587 | urb->actual_length); | 586 | |
588 | tty_flip_buffer_push(tty); | 587 | usb_serial_debug_data(&port->dev, __func__, |
589 | 588 | urb->actual_length, data); | |
590 | tty_kref_put(tty); | ||
591 | usb_serial_debug_data(&port->dev, __func__, | ||
592 | urb->actual_length, data); | ||
593 | } | ||
594 | } else { | 589 | } else { |
595 | dev_dbg(&port->dev, "%s: empty read urb" | 590 | dev_dbg(&port->dev, "%s: empty read urb" |
596 | " received\n", __func__); | 591 | " received\n", __func__); |
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index a42536af1256..91ff8e3bddbd 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
@@ -462,7 +462,6 @@ static void spcp8x5_process_read_urb(struct urb *urb) | |||
462 | { | 462 | { |
463 | struct usb_serial_port *port = urb->context; | 463 | struct usb_serial_port *port = urb->context; |
464 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | 464 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
465 | struct tty_struct *tty; | ||
466 | unsigned char *data = urb->transfer_buffer; | 465 | unsigned char *data = urb->transfer_buffer; |
467 | unsigned long flags; | 466 | unsigned long flags; |
468 | u8 status; | 467 | u8 status; |
@@ -481,9 +480,6 @@ static void spcp8x5_process_read_urb(struct urb *urb) | |||
481 | if (!urb->actual_length) | 480 | if (!urb->actual_length) |
482 | return; | 481 | return; |
483 | 482 | ||
484 | tty = tty_port_tty_get(&port->port); | ||
485 | if (!tty) | ||
486 | return; | ||
487 | 483 | ||
488 | if (status & UART_STATE_TRANSIENT_MASK) { | 484 | if (status & UART_STATE_TRANSIENT_MASK) { |
489 | /* break takes precedence over parity, which takes precedence | 485 | /* break takes precedence over parity, which takes precedence |
@@ -498,17 +494,21 @@ static void spcp8x5_process_read_urb(struct urb *urb) | |||
498 | 494 | ||
499 | /* overrun is special, not associated with a char */ | 495 | /* overrun is special, not associated with a char */ |
500 | if (status & UART_OVERRUN_ERROR) | 496 | if (status & UART_OVERRUN_ERROR) |
501 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 497 | tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); |
502 | 498 | ||
503 | if (status & UART_DCD) | 499 | if (status & UART_DCD) { |
504 | usb_serial_handle_dcd_change(port, tty, | 500 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
505 | priv->line_status & MSR_STATUS_LINE_DCD); | 501 | if (tty) { |
502 | usb_serial_handle_dcd_change(port, tty, | ||
503 | priv->line_status & MSR_STATUS_LINE_DCD); | ||
504 | tty_kref_put(tty); | ||
505 | } | ||
506 | } | ||
506 | } | 507 | } |
507 | 508 | ||
508 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 509 | tty_insert_flip_string_fixed_flag(&port->port, data, tty_flag, |
509 | urb->actual_length); | 510 | urb->actual_length); |
510 | tty_flip_buffer_push(tty); | 511 | tty_flip_buffer_push(&port->port); |
511 | tty_kref_put(tty); | ||
512 | } | 512 | } |
513 | 513 | ||
514 | static int spcp8x5_wait_modem_info(struct usb_serial_port *port, | 514 | static int spcp8x5_wait_modem_info(struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index d938396171e8..b57cf841c5b6 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -579,8 +579,7 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, | |||
579 | 579 | ||
580 | } | 580 | } |
581 | 581 | ||
582 | static int ssu100_process_packet(struct urb *urb, | 582 | static void ssu100_process_read_urb(struct urb *urb) |
583 | struct tty_struct *tty) | ||
584 | { | 583 | { |
585 | struct usb_serial_port *port = urb->context; | 584 | struct usb_serial_port *port = urb->context; |
586 | char *packet = (char *)urb->transfer_buffer; | 585 | char *packet = (char *)urb->transfer_buffer; |
@@ -595,7 +594,8 @@ static int ssu100_process_packet(struct urb *urb, | |||
595 | if (packet[2] == 0x00) { | 594 | if (packet[2] == 0x00) { |
596 | ssu100_update_lsr(port, packet[3], &flag); | 595 | ssu100_update_lsr(port, packet[3], &flag); |
597 | if (flag == TTY_OVERRUN) | 596 | if (flag == TTY_OVERRUN) |
598 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 597 | tty_insert_flip_char(&port->port, 0, |
598 | TTY_OVERRUN); | ||
599 | } | 599 | } |
600 | if (packet[2] == 0x01) | 600 | if (packet[2] == 0x01) |
601 | ssu100_update_msr(port, packet[3]); | 601 | ssu100_update_msr(port, packet[3]); |
@@ -606,34 +606,17 @@ static int ssu100_process_packet(struct urb *urb, | |||
606 | ch = packet; | 606 | ch = packet; |
607 | 607 | ||
608 | if (!len) | 608 | if (!len) |
609 | return 0; /* status only */ | 609 | return; /* status only */ |
610 | 610 | ||
611 | if (port->port.console && port->sysrq) { | 611 | if (port->port.console && port->sysrq) { |
612 | for (i = 0; i < len; i++, ch++) { | 612 | for (i = 0; i < len; i++, ch++) { |
613 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 613 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
614 | tty_insert_flip_char(tty, *ch, flag); | 614 | tty_insert_flip_char(&port->port, *ch, flag); |
615 | } | 615 | } |
616 | } else | 616 | } else |
617 | tty_insert_flip_string_fixed_flag(tty, ch, flag, len); | 617 | tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len); |
618 | |||
619 | return len; | ||
620 | } | ||
621 | |||
622 | static void ssu100_process_read_urb(struct urb *urb) | ||
623 | { | ||
624 | struct usb_serial_port *port = urb->context; | ||
625 | struct tty_struct *tty; | ||
626 | int count; | ||
627 | |||
628 | tty = tty_port_tty_get(&port->port); | ||
629 | if (!tty) | ||
630 | return; | ||
631 | |||
632 | count = ssu100_process_packet(urb, tty); | ||
633 | 618 | ||
634 | if (count) | 619 | tty_flip_buffer_push(&port->port); |
635 | tty_flip_buffer_push(tty); | ||
636 | tty_kref_put(tty); | ||
637 | } | 620 | } |
638 | 621 | ||
639 | static struct usb_serial_driver ssu100_device = { | 622 | static struct usb_serial_driver ssu100_device = { |
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index 701fffa8431f..be05e6caf9a3 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c | |||
@@ -48,7 +48,6 @@ static void symbol_int_callback(struct urb *urb) | |||
48 | unsigned char *data = urb->transfer_buffer; | 48 | unsigned char *data = urb->transfer_buffer; |
49 | struct usb_serial_port *port = priv->port; | 49 | struct usb_serial_port *port = priv->port; |
50 | int status = urb->status; | 50 | int status = urb->status; |
51 | struct tty_struct *tty; | ||
52 | int result; | 51 | int result; |
53 | int data_length; | 52 | int data_length; |
54 | 53 | ||
@@ -82,12 +81,8 @@ static void symbol_int_callback(struct urb *urb) | |||
82 | * we pretty much just ignore the size and send everything | 81 | * we pretty much just ignore the size and send everything |
83 | * else to the tty layer. | 82 | * else to the tty layer. |
84 | */ | 83 | */ |
85 | tty = tty_port_tty_get(&port->port); | 84 | tty_insert_flip_string(&port->port, &data[1], data_length); |
86 | if (tty) { | 85 | tty_flip_buffer_push(&port->port); |
87 | tty_insert_flip_string(tty, &data[1], data_length); | ||
88 | tty_flip_buffer_push(tty); | ||
89 | tty_kref_put(tty); | ||
90 | } | ||
91 | } else { | 86 | } else { |
92 | dev_dbg(&priv->udev->dev, | 87 | dev_dbg(&priv->udev->dev, |
93 | "Improper amount of data received from the device, " | 88 | "Improper amount of data received from the device, " |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index f2530d2ef3c4..39cb9b807c3c 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -121,8 +121,8 @@ static void ti_interrupt_callback(struct urb *urb); | |||
121 | static void ti_bulk_in_callback(struct urb *urb); | 121 | static void ti_bulk_in_callback(struct urb *urb); |
122 | static void ti_bulk_out_callback(struct urb *urb); | 122 | static void ti_bulk_out_callback(struct urb *urb); |
123 | 123 | ||
124 | static void ti_recv(struct device *dev, struct tty_struct *tty, | 124 | static void ti_recv(struct usb_serial_port *port, unsigned char *data, |
125 | unsigned char *data, int length); | 125 | int length); |
126 | static void ti_send(struct ti_port *tport); | 126 | static void ti_send(struct ti_port *tport); |
127 | static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); | 127 | static int ti_set_mcr(struct ti_port *tport, unsigned int mcr); |
128 | static int ti_get_lsr(struct ti_port *tport); | 128 | static int ti_get_lsr(struct ti_port *tport); |
@@ -1118,7 +1118,6 @@ static void ti_bulk_in_callback(struct urb *urb) | |||
1118 | struct device *dev = &urb->dev->dev; | 1118 | struct device *dev = &urb->dev->dev; |
1119 | int status = urb->status; | 1119 | int status = urb->status; |
1120 | int retval = 0; | 1120 | int retval = 0; |
1121 | struct tty_struct *tty; | ||
1122 | 1121 | ||
1123 | switch (status) { | 1122 | switch (status) { |
1124 | case 0: | 1123 | case 0: |
@@ -1145,24 +1144,18 @@ static void ti_bulk_in_callback(struct urb *urb) | |||
1145 | return; | 1144 | return; |
1146 | } | 1145 | } |
1147 | 1146 | ||
1148 | tty = tty_port_tty_get(&port->port); | 1147 | if (urb->actual_length) { |
1149 | if (tty) { | 1148 | usb_serial_debug_data(dev, __func__, urb->actual_length, |
1150 | if (urb->actual_length) { | 1149 | urb->transfer_buffer); |
1151 | usb_serial_debug_data(dev, __func__, urb->actual_length, | ||
1152 | urb->transfer_buffer); | ||
1153 | 1150 | ||
1154 | if (!tport->tp_is_open) | 1151 | if (!tport->tp_is_open) |
1155 | dev_dbg(dev, "%s - port closed, dropping data\n", | 1152 | dev_dbg(dev, "%s - port closed, dropping data\n", |
1156 | __func__); | 1153 | __func__); |
1157 | else | 1154 | else |
1158 | ti_recv(&urb->dev->dev, tty, | 1155 | ti_recv(port, urb->transfer_buffer, urb->actual_length); |
1159 | urb->transfer_buffer, | 1156 | spin_lock(&tport->tp_lock); |
1160 | urb->actual_length); | 1157 | tport->tp_icount.rx += urb->actual_length; |
1161 | spin_lock(&tport->tp_lock); | 1158 | spin_unlock(&tport->tp_lock); |
1162 | tport->tp_icount.rx += urb->actual_length; | ||
1163 | spin_unlock(&tport->tp_lock); | ||
1164 | } | ||
1165 | tty_kref_put(tty); | ||
1166 | } | 1159 | } |
1167 | 1160 | ||
1168 | exit: | 1161 | exit: |
@@ -1210,24 +1203,23 @@ static void ti_bulk_out_callback(struct urb *urb) | |||
1210 | } | 1203 | } |
1211 | 1204 | ||
1212 | 1205 | ||
1213 | static void ti_recv(struct device *dev, struct tty_struct *tty, | 1206 | static void ti_recv(struct usb_serial_port *port, unsigned char *data, |
1214 | unsigned char *data, int length) | 1207 | int length) |
1215 | { | 1208 | { |
1216 | int cnt; | 1209 | int cnt; |
1217 | 1210 | ||
1218 | do { | 1211 | do { |
1219 | cnt = tty_insert_flip_string(tty, data, length); | 1212 | cnt = tty_insert_flip_string(&port->port, data, length); |
1220 | if (cnt < length) { | 1213 | if (cnt < length) { |
1221 | dev_err(dev, "%s - dropping data, %d bytes lost\n", | 1214 | dev_err(&port->dev, "%s - dropping data, %d bytes lost\n", |
1222 | __func__, length - cnt); | 1215 | __func__, length - cnt); |
1223 | if (cnt == 0) | 1216 | if (cnt == 0) |
1224 | break; | 1217 | break; |
1225 | } | 1218 | } |
1226 | tty_flip_buffer_push(tty); | 1219 | tty_flip_buffer_push(&port->port); |
1227 | data += cnt; | 1220 | data += cnt; |
1228 | length -= cnt; | 1221 | length -= cnt; |
1229 | } while (length > 0); | 1222 | } while (length > 0); |
1230 | |||
1231 | } | 1223 | } |
1232 | 1224 | ||
1233 | 1225 | ||
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 1355a6cd4508..571965aa1cc0 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -273,7 +273,6 @@ static void usb_wwan_indat_callback(struct urb *urb) | |||
273 | int err; | 273 | int err; |
274 | int endpoint; | 274 | int endpoint; |
275 | struct usb_serial_port *port; | 275 | struct usb_serial_port *port; |
276 | struct tty_struct *tty; | ||
277 | struct device *dev; | 276 | struct device *dev; |
278 | unsigned char *data = urb->transfer_buffer; | 277 | unsigned char *data = urb->transfer_buffer; |
279 | int status = urb->status; | 278 | int status = urb->status; |
@@ -286,16 +285,12 @@ static void usb_wwan_indat_callback(struct urb *urb) | |||
286 | dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n", | 285 | dev_dbg(dev, "%s: nonzero status: %d on endpoint %02x.\n", |
287 | __func__, status, endpoint); | 286 | __func__, status, endpoint); |
288 | } else { | 287 | } else { |
289 | tty = tty_port_tty_get(&port->port); | 288 | if (urb->actual_length) { |
290 | if (tty) { | 289 | tty_insert_flip_string(&port->port, data, |
291 | if (urb->actual_length) { | 290 | urb->actual_length); |
292 | tty_insert_flip_string(tty, data, | 291 | tty_flip_buffer_push(&port->port); |
293 | urb->actual_length); | 292 | } else |
294 | tty_flip_buffer_push(tty); | 293 | dev_dbg(dev, "%s: empty read urb received\n", __func__); |
295 | } else | ||
296 | dev_dbg(dev, "%s: empty read urb received\n", __func__); | ||
297 | tty_kref_put(tty); | ||
298 | } | ||
299 | 294 | ||
300 | /* Resubmit urb so we continue receiving */ | 295 | /* Resubmit urb so we continue receiving */ |
301 | err = usb_submit_urb(urb, GFP_ATOMIC); | 296 | err = usb_submit_urb(urb, GFP_ATOMIC); |
diff --git a/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c index 97f79356141e..53846cb534d4 100644 --- a/drivers/video/auo_k190x.c +++ b/drivers/video/auo_k190x.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/gpio.h> | 13 | #include <linux/gpio.h> |
14 | #include <linux/platform_device.h> | ||
14 | #include <linux/pm_runtime.h> | 15 | #include <linux/pm_runtime.h> |
15 | #include <linux/fb.h> | 16 | #include <linux/fb.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c index 469cf0f109d2..fdbb6ee5027c 100644 --- a/drivers/video/backlight/ot200_bl.c +++ b/drivers/video/backlight/ot200_bl.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/fb.h> | 14 | #include <linux/fb.h> |
15 | #include <linux/backlight.h> | 15 | #include <linux/backlight.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/platform_device.h> | ||
17 | #include <linux/cs5535.h> | 18 | #include <linux/cs5535.h> |
18 | 19 | ||
19 | static struct cs5535_mfgpt_timer *pwm_timer; | 20 | static struct cs5535_mfgpt_timer *pwm_timer; |
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c index 5a7af0deced2..f00980607b8f 100644 --- a/drivers/video/clps711xfb.c +++ b/drivers/video/clps711xfb.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/fb.h> | 26 | #include <linux/fb.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/platform_device.h> | ||
29 | 30 | ||
30 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
31 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c index 3cd29a4fc10a..c70cb8926df6 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_common.c +++ b/drivers/video/exynos/exynos_mipi_dsi_common.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/memory.h> | 26 | #include <linux/memory.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/irqreturn.h> | ||
28 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
29 | 30 | ||
30 | #include <video/mipi_display.h> | 31 | #include <video/mipi_display.h> |
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c index 0ef38ce72af6..95cb99a1fe2d 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c +++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/ctype.h> | 23 | #include <linux/ctype.h> |
24 | #include <linux/platform_device.h> | ||
24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
25 | 26 | ||
26 | #include <video/exynos_mipi_dsim.h> | 27 | #include <video/exynos_mipi_dsim.h> |