diff options
author | Jiri Slaby <jslaby@suse.cz> | 2012-04-02 07:54:44 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-04-09 15:02:44 -0400 |
commit | 467712c916764859f7ea698d38d03c51bb827da8 (patch) | |
tree | 1661912712c7eb15e791f38da01382b990998573 /drivers | |
parent | a85dd82c966a4eb1f4502e62cf49d715d191cefc (diff) |
TTY: 68328serial, propagate tty
We need tty at some places, but info->tty might be NULL at those. Let
us propagate tty from callers where we know we have a valid tty. This
will make a switch to tty refcounting simpler.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org
Acked-by: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/tty/serial/68328serial.c | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index e3a1c557fe95..fde573b32ce0 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
@@ -140,7 +140,7 @@ m68328_uart *uart_addr = (m68328_uart *)USTCNT_ADDR; | |||
140 | 140 | ||
141 | struct tty_driver *serial_driver; | 141 | struct tty_driver *serial_driver; |
142 | 142 | ||
143 | static void change_speed(struct m68k_serial *info); | 143 | static void change_speed(struct m68k_serial *info, struct tty_struct *tty); |
144 | 144 | ||
145 | /* | 145 | /* |
146 | * Setup for console. Argument comes from the boot command line. | 146 | * Setup for console. Argument comes from the boot command line. |
@@ -263,9 +263,9 @@ static void rs_start(struct tty_struct *tty) | |||
263 | local_irq_restore(flags); | 263 | local_irq_restore(flags); |
264 | } | 264 | } |
265 | 265 | ||
266 | static void receive_chars(struct m68k_serial *info, unsigned short rx) | 266 | static void receive_chars(struct m68k_serial *info, struct tty_struct *tty, |
267 | unsigned short rx) | ||
267 | { | 268 | { |
268 | struct tty_struct *tty = info->tty; | ||
269 | m68328_uart *uart = &uart_addr[info->line]; | 269 | m68328_uart *uart = &uart_addr[info->line]; |
270 | unsigned char ch, flag; | 270 | unsigned char ch, flag; |
271 | 271 | ||
@@ -317,7 +317,7 @@ clear_and_exit: | |||
317 | return; | 317 | return; |
318 | } | 318 | } |
319 | 319 | ||
320 | static void transmit_chars(struct m68k_serial *info) | 320 | static void transmit_chars(struct m68k_serial *info, struct tty_struct *tty) |
321 | { | 321 | { |
322 | m68328_uart *uart = &uart_addr[info->line]; | 322 | m68328_uart *uart = &uart_addr[info->line]; |
323 | 323 | ||
@@ -328,7 +328,7 @@ static void transmit_chars(struct m68k_serial *info) | |||
328 | goto clear_and_return; | 328 | goto clear_and_return; |
329 | } | 329 | } |
330 | 330 | ||
331 | if((info->xmit_cnt <= 0) || info->tty->stopped) { | 331 | if ((info->xmit_cnt <= 0) || !tty || tty->stopped) { |
332 | /* That's peculiar... TX ints off */ | 332 | /* That's peculiar... TX ints off */ |
333 | uart->ustcnt &= ~USTCNT_TX_INTR_MASK; | 333 | uart->ustcnt &= ~USTCNT_TX_INTR_MASK; |
334 | goto clear_and_return; | 334 | goto clear_and_return; |
@@ -356,6 +356,7 @@ clear_and_return: | |||
356 | irqreturn_t rs_interrupt(int irq, void *dev_id) | 356 | irqreturn_t rs_interrupt(int irq, void *dev_id) |
357 | { | 357 | { |
358 | struct m68k_serial *info = dev_id; | 358 | struct m68k_serial *info = dev_id; |
359 | struct tty_struct *tty = info->tty; | ||
359 | m68328_uart *uart; | 360 | m68328_uart *uart; |
360 | unsigned short rx; | 361 | unsigned short rx; |
361 | unsigned short tx; | 362 | unsigned short tx; |
@@ -366,15 +367,17 @@ irqreturn_t rs_interrupt(int irq, void *dev_id) | |||
366 | #ifdef USE_INTS | 367 | #ifdef USE_INTS |
367 | tx = uart->utx.w; | 368 | tx = uart->utx.w; |
368 | 369 | ||
369 | if (rx & URX_DATA_READY) receive_chars(info, rx); | 370 | if (rx & URX_DATA_READY) |
370 | if (tx & UTX_TX_AVAIL) transmit_chars(info); | 371 | receive_chars(info, tty, rx); |
372 | if (tx & UTX_TX_AVAIL) | ||
373 | transmit_chars(info, tty); | ||
371 | #else | 374 | #else |
372 | receive_chars(info, rx); | 375 | receive_chars(info, tty, rx); |
373 | #endif | 376 | #endif |
374 | return IRQ_HANDLED; | 377 | return IRQ_HANDLED; |
375 | } | 378 | } |
376 | 379 | ||
377 | static int startup(struct m68k_serial * info) | 380 | static int startup(struct m68k_serial *info, struct tty_struct *tty) |
378 | { | 381 | { |
379 | m68328_uart *uart = &uart_addr[info->line]; | 382 | m68328_uart *uart = &uart_addr[info->line]; |
380 | unsigned long flags; | 383 | unsigned long flags; |
@@ -409,15 +412,15 @@ static int startup(struct m68k_serial * info) | |||
409 | uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK; | 412 | uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK; |
410 | #endif | 413 | #endif |
411 | 414 | ||
412 | if (info->tty) | 415 | if (tty) |
413 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 416 | clear_bit(TTY_IO_ERROR, &tty->flags); |
414 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 417 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
415 | 418 | ||
416 | /* | 419 | /* |
417 | * and set the speed of the serial port | 420 | * and set the speed of the serial port |
418 | */ | 421 | */ |
419 | 422 | ||
420 | change_speed(info); | 423 | change_speed(info, tty); |
421 | 424 | ||
422 | info->tport.flags |= ASYNC_INITIALIZED; | 425 | info->tport.flags |= ASYNC_INITIALIZED; |
423 | local_irq_restore(flags); | 426 | local_irq_restore(flags); |
@@ -428,7 +431,7 @@ static int startup(struct m68k_serial * info) | |||
428 | * This routine will shutdown a serial port; interrupts are disabled, and | 431 | * This routine will shutdown a serial port; interrupts are disabled, and |
429 | * DTR is dropped if the hangup on close termio flag is on. | 432 | * DTR is dropped if the hangup on close termio flag is on. |
430 | */ | 433 | */ |
431 | static void shutdown(struct m68k_serial * info) | 434 | static void shutdown(struct m68k_serial *info, struct tty_struct *tty) |
432 | { | 435 | { |
433 | m68328_uart *uart = &uart_addr[info->line]; | 436 | m68328_uart *uart = &uart_addr[info->line]; |
434 | unsigned long flags; | 437 | unsigned long flags; |
@@ -444,8 +447,8 @@ static void shutdown(struct m68k_serial * info) | |||
444 | info->xmit_buf = 0; | 447 | info->xmit_buf = 0; |
445 | } | 448 | } |
446 | 449 | ||
447 | if (info->tty) | 450 | if (tty) |
448 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 451 | set_bit(TTY_IO_ERROR, &tty->flags); |
449 | 452 | ||
450 | info->tport.flags &= ~ASYNC_INITIALIZED; | 453 | info->tport.flags &= ~ASYNC_INITIALIZED; |
451 | local_irq_restore(flags); | 454 | local_irq_restore(flags); |
@@ -503,7 +506,7 @@ struct { | |||
503 | * This routine is called to set the UART divisor registers to match | 506 | * This routine is called to set the UART divisor registers to match |
504 | * the specified baud rate for a serial port. | 507 | * the specified baud rate for a serial port. |
505 | */ | 508 | */ |
506 | static void change_speed(struct m68k_serial *info) | 509 | static void change_speed(struct m68k_serial *info, struct tty_struct *tty) |
507 | { | 510 | { |
508 | m68328_uart *uart = &uart_addr[info->line]; | 511 | m68328_uart *uart = &uart_addr[info->line]; |
509 | unsigned short port; | 512 | unsigned short port; |
@@ -511,9 +514,7 @@ static void change_speed(struct m68k_serial *info) | |||
511 | unsigned cflag; | 514 | unsigned cflag; |
512 | int i; | 515 | int i; |
513 | 516 | ||
514 | if (!info->tty || !info->tty->termios) | 517 | cflag = tty->termios->c_cflag; |
515 | return; | ||
516 | cflag = info->tty->termios->c_cflag; | ||
517 | if (!(port = info->port)) | 518 | if (!(port = info->port)) |
518 | return; | 519 | return; |
519 | 520 | ||
@@ -832,7 +833,7 @@ static int get_serial_info(struct m68k_serial * info, | |||
832 | return 0; | 833 | return 0; |
833 | } | 834 | } |
834 | 835 | ||
835 | static int set_serial_info(struct m68k_serial * info, | 836 | static int set_serial_info(struct m68k_serial *info, struct tty_struct *tty, |
836 | struct serial_struct * new_info) | 837 | struct serial_struct * new_info) |
837 | { | 838 | { |
838 | struct tty_port *port = &info->tport; | 839 | struct tty_port *port = &info->tport; |
@@ -875,7 +876,7 @@ static int set_serial_info(struct m68k_serial * info, | |||
875 | port->closing_wait = new_serial.closing_wait; | 876 | port->closing_wait = new_serial.closing_wait; |
876 | 877 | ||
877 | check_and_exit: | 878 | check_and_exit: |
878 | retval = startup(info); | 879 | retval = startup(info, tty); |
879 | return retval; | 880 | return retval; |
880 | } | 881 | } |
881 | 882 | ||
@@ -961,7 +962,7 @@ static int rs_ioctl(struct tty_struct *tty, | |||
961 | return get_serial_info(info, | 962 | return get_serial_info(info, |
962 | (struct serial_struct *) arg); | 963 | (struct serial_struct *) arg); |
963 | case TIOCSSERIAL: | 964 | case TIOCSSERIAL: |
964 | return set_serial_info(info, | 965 | return set_serial_info(info, tty, |
965 | (struct serial_struct *) arg); | 966 | (struct serial_struct *) arg); |
966 | case TIOCSERGETLSR: /* Get line status register */ | 967 | case TIOCSERGETLSR: /* Get line status register */ |
967 | return get_lsr_info(info, (unsigned int *) arg); | 968 | return get_lsr_info(info, (unsigned int *) arg); |
@@ -980,7 +981,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
980 | { | 981 | { |
981 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; | 982 | struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; |
982 | 983 | ||
983 | change_speed(info); | 984 | change_speed(info, tty); |
984 | 985 | ||
985 | if ((old_termios->c_cflag & CRTSCTS) && | 986 | if ((old_termios->c_cflag & CRTSCTS) && |
986 | !(tty->termios->c_cflag & CRTSCTS)) { | 987 | !(tty->termios->c_cflag & CRTSCTS)) { |
@@ -1056,7 +1057,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1056 | uart->ustcnt &= ~USTCNT_RXEN; | 1057 | uart->ustcnt &= ~USTCNT_RXEN; |
1057 | uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK); | 1058 | uart->ustcnt &= ~(USTCNT_RXEN | USTCNT_RX_INTR_MASK); |
1058 | 1059 | ||
1059 | shutdown(info); | 1060 | shutdown(info, tty); |
1060 | rs_flush_buffer(tty); | 1061 | rs_flush_buffer(tty); |
1061 | 1062 | ||
1062 | tty_ldisc_flush(tty); | 1063 | tty_ldisc_flush(tty); |
@@ -1094,7 +1095,7 @@ void rs_hangup(struct tty_struct *tty) | |||
1094 | return; | 1095 | return; |
1095 | 1096 | ||
1096 | rs_flush_buffer(tty); | 1097 | rs_flush_buffer(tty); |
1097 | shutdown(info); | 1098 | shutdown(info, tty); |
1098 | info->tport.count = 0; | 1099 | info->tport.count = 0; |
1099 | info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; | 1100 | info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; |
1100 | info->tty = NULL; | 1101 | info->tty = NULL; |
@@ -1214,7 +1215,7 @@ int rs_open(struct tty_struct *tty, struct file * filp) | |||
1214 | /* | 1215 | /* |
1215 | * Start up serial port | 1216 | * Start up serial port |
1216 | */ | 1217 | */ |
1217 | retval = startup(info); | 1218 | retval = startup(info, tty); |
1218 | if (retval) | 1219 | if (retval) |
1219 | return retval; | 1220 | return retval; |
1220 | 1221 | ||