diff options
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> |
