1/* 2 * dz.c: Serial port driver for DECStations equiped 3 * with the DZ chipset. 4 * 5 * Copyright (C) 1998 Olivier A. D. Lebaillif 6 * 7 * Email: olivier.lebaillif@ifrsys.com 8 * 9 * [31-AUG-98] triemer 10 * Changed IRQ to use Harald's dec internals interrupts.h 11 * removed base_addr code - moving address assignment to setup.c 12 * Changed name of dz_init to rs_init to be consistent with tc code 13 * [13-NOV-98] triemer fixed code to receive characters 14 * after patches by harald to irq code. 15 * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout 16 * field from "current" - somewhere between 2.1.121 and 2.1.131 17 Qua Jun 27 15:02:26 BRT 2001 18 * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups 19 * 20 * Parts (C) 1999 David Airlie, airlied@linux.ie 21 * [07-SEP-99] Bugfixes 22 */ 23 24#define DEBUG_DZ 1 25 26#include <linux/config.h> 27#include <linux/version.h> 28#include <linux/kernel.h> 29#include <linux/sched.h> 30#include <linux/init.h> 31#include <linux/slab.h> 32#include <linux/mm.h> 33#include <linux/major.h> 34#include <linux/module.h> 35#include <linux/param.h> 36#include <linux/tqueue.h> 37#include <linux/interrupt.h> 38 39#include <linux/console.h> 40#include <linux/tty.h> 41#include <linux/tty_flip.h> 42#include <linux/serial.h> 43 44#include <linux/ptrace.h> 45#include <linux/fs.h> 46 47#include <asm/bootinfo.h> 48#include <asm/dec/interrupts.h> 49#include <asm/dec/kn01.h> 50#include <asm/dec/kn02.h> 51#include <asm/dec/machtype.h> 52#include <asm/dec/prom.h> 53#include <asm/irq.h> 54#include <asm/system.h> 55#include <asm/uaccess.h> 56 57#define CONSOLE_LINE (3) /* for definition of struct console */ 58 59#include "dz.h" 60 61#define DZ_INTR_DEBUG 1 62 63DECLARE_TASK_QUEUE(tq_serial); 64 65static struct dz_serial *lines[4]; 66static unsigned char tmp_buffer[256]; 67 68#ifdef DEBUG_DZ 69/* 70 * debugging code to send out chars via prom 71 */ 72static void debug_console(const char *s, int count) 73{ 74 unsigned i; 75 76 for (i = 0; i < count; i++) { 77 if (*s == 10) 78 prom_printf("%c", 13); 79 prom_printf("%c", *s++); 80 } 81} 82#endif 83 84/* 85 * ------------------------------------------------------------ 86 * dz_in () and dz_out () 87 * 88 * These routines are used to access the registers of the DZ 89 * chip, hiding relocation differences between implementation. 90 * ------------------------------------------------------------ 91 */ 92 93static inline unsigned short dz_in(struct dz_serial *info, unsigned offset) 94{ 95 volatile unsigned short *addr = 96 (volatile unsigned short *) (info->port + offset); 97 return *addr; 98} 99 100static inline void dz_out(struct dz_serial *info, unsigned offset, 101 unsigned short value) 102{ 103 104 volatile unsigned short *addr = 105 (volatile unsigned short *) (info->port + offset); 106 *addr = value; 107} 108 109/* 110 * ------------------------------------------------------------ 111 * rs_stop () and rs_start () 112 * 113 * These routines are called before setting or resetting 114 * tty->stopped. They enable or disable transmitter interrupts, 115 * as necessary. 116 * ------------------------------------------------------------ 117 */ 118 119static void dz_stop(struct tty_struct *tty) 120{ 121 struct dz_serial *info; 122 unsigned short mask, tmp; 123 124 if (tty == 0) 125 return; 126 127 info = (struct dz_serial *) tty->driver_data; 128 129 mask = 1 << info->line; 130 tmp = dz_in(info, DZ_TCR); /* read the TX flag */ 131 132 tmp &= ~mask; /* clear the TX flag */ 133 dz_out(info, DZ_TCR, tmp); 134} 135 136static void dz_start(struct tty_struct *tty) 137{ 138 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 139 unsigned short mask, tmp; 140 141 mask = 1 << info->line; 142 tmp = dz_in(info, DZ_TCR); /* read the TX flag */ 143 144 tmp |= mask; /* set the TX flag */ 145 dz_out(info, DZ_TCR, tmp); 146 147} 148 149/* 150 * ------------------------------------------------------------ 151 * Here starts the interrupt handling routines. All of the 152 * following subroutines are declared as inline and are folded 153 * into dz_interrupt. They were separated out for readability's 154 * sake. 155 * 156 * Note: rs_interrupt() is a "fast" interrupt, which means that it 157 * runs with interrupts turned off. People who may want to modify 158 * rs_interrupt() should try to keep the interrupt handler as fast as 159 * possible. After you are done making modifications, it is not a bad 160 * idea to do: 161 * 162 * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer dz.c 163 * 164 * and look at the resulting assemble code in serial.s. 165 * 166 * ------------------------------------------------------------ 167 */ 168 169/* 170 * ------------------------------------------------------------ 171 * dz_sched_event () 172 * 173 * This routine is used by the interrupt handler to schedule 174 * processing in the software interrupt portion of the driver. 175 * ------------------------------------------------------------ 176 */ 177static inline void dz_sched_event(struct dz_serial *info, int event) 178{ 179 info->event |= 1 << event; 180 queue_task(&info->tqueue, &tq_serial); 181 mark_bh(SERIAL_BH); 182} 183 184/* 185 * ------------------------------------------------------------ 186 * receive_char () 187 * 188 * This routine deals with inputs from any lines. 189 * ------------------------------------------------------------ 190 */ 191static inline void receive_chars(struct dz_serial *info_in) 192{ 193 194 struct dz_serial *info; 195 struct tty_struct *tty = 0; 196 struct async_icount *icount; 197 int ignore = 0; 198 unsigned short status, tmp; 199 unsigned char ch; 200 201 /* this code is going to be a problem... 202 the call to tty_flip_buffer is going to need 203 to be rethought... 204 */ 205 do { 206 status = dz_in(info_in, DZ_RBUF); 207 info = lines[LINE(status)]; 208 209 /* punt so we don't get duplicate characters */ 210 if (!(status & DZ_DVAL)) 211 goto ignore_char; 212 213 ch = UCHAR(status); /* grab the char */ 214 215 216 tty = info->tty; /* now tty points to the proper dev */ 217 icount = &info->icount; 218 219 if (!tty) 220 break; 221 if (tty->flip.count >= TTY_FLIPBUF_SIZE) 222 break; 223 224 *tty->flip.char_buf_ptr = ch; 225 *tty->flip.flag_buf_ptr = 0; 226 icount->rx++; 227 228 /* keep track of the statistics */ 229 if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) { 230 if (status & DZ_PERR) /* parity error */ 231 icount->parity++; 232 else if (status & DZ_FERR) /* frame error */ 233 icount->frame++; 234 if (status & DZ_OERR) /* overrun error */ 235 icount->overrun++; 236 237 /* check to see if we should ignore the character 238 and mask off conditions that should be ignored 239 */ 240 241 if (status & info->ignore_status_mask) { 242 if (++ignore > 100) 243 break; 244 goto ignore_char; 245 } 246 /* mask off the error conditions we want to ignore */ 247 tmp = status & info->read_status_mask; 248 249 if (tmp & DZ_PERR) { 250 *tty->flip.flag_buf_ptr = TTY_PARITY; 251 debug_console("PERR\n", 5); 252 } else if (tmp & DZ_FERR) { 253 *tty->flip.flag_buf_ptr = TTY_FRAME; 254 debug_console("FERR\n", 5); 255 } 256 if (tmp & DZ_OERR) { 257 debug_console("OERR\n", 5); 258 if (tty->flip.count < TTY_FLIPBUF_SIZE) { 259 tty->flip.count++; 260 tty->flip.flag_buf_ptr++; 261 tty->flip.char_buf_ptr++; 262 *tty->flip.flag_buf_ptr = TTY_OVERRUN; 263 } 264 } 265 } 266 tty->flip.flag_buf_ptr++; 267 tty->flip.char_buf_ptr++; 268 tty->flip.count++; 269 ignore_char: 270 } while (status & DZ_DVAL); 271 272 if (tty) 273 tty_flip_buffer_push(tty); 274} 275 276/* 277 * ------------------------------------------------------------ 278 * transmit_char () 279 * 280 * This routine deals with outputs to any lines. 281 * ------------------------------------------------------------ 282 */ 283static inline void transmit_chars(struct dz_serial *info) 284{ 285 unsigned char tmp; 286 287 288 289 if (info->x_char) { /* XON/XOFF chars */ 290 dz_out(info, DZ_TDR, info->x_char); 291 info->icount.tx++; 292 info->x_char = 0; 293 return; 294 } 295 /* if nothing to do or stopped or hardware stopped */ 296 if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped) { 297 dz_stop(info->tty); 298 return; 299 } 300 /* 301 * if something to do ... (rember the dz has no output fifo so we go 302 * one char at a time :-< 303 */ 304 tmp = (unsigned short) info->xmit_buf[info->xmit_tail++]; 305 dz_out(info, DZ_TDR, tmp); 306 info->xmit_tail = info->xmit_tail & (DZ_XMIT_SIZE - 1); 307 info->icount.tx++; 308 309 if (--info->xmit_cnt < WAKEUP_CHARS) 310 dz_sched_event(info, DZ_EVENT_WRITE_WAKEUP); 311 312 313 /* Are we done */ 314 if (info->xmit_cnt <= 0) 315 dz_stop(info->tty); 316} 317 318/* 319 * ------------------------------------------------------------ 320 * check_modem_status () 321 * 322 * Only valid for the MODEM line duh ! 323 * ------------------------------------------------------------ 324 */ 325static inline void check_modem_status(struct dz_serial *info) 326{ 327 unsigned short status; 328 329 /* if not ne modem line just return */ 330 if (info->line != DZ_MODEM) 331 return; 332 333 status = dz_in(info, DZ_MSR); 334 335 /* it's easy, since DSR2 is the only bit in the register */ 336 if (status) 337 info->icount.dsr++; 338} 339 340/* 341 * ------------------------------------------------------------ 342 * dz_interrupt () 343 * 344 * this is the main interrupt routine for the DZ chip. 345 * It deals with the multiple ports. 346 * ------------------------------------------------------------ 347 */ 348static void dz_interrupt(int irq, void *dev, struct pt_regs *regs) 349{ 350 struct dz_serial *info; 351 unsigned short status; 352 353 /* get the reason why we just got an irq */ 354 status = dz_in((struct dz_serial *) dev, DZ_CSR); 355 info = lines[LINE(status)]; /* re-arrange info the proper port */ 356 357 if (status & DZ_RDONE) 358 receive_chars(info); /* the receive function */ 359 360 if (status & DZ_TRDY) 361 transmit_chars(info); 362} 363 364/* 365 * ------------------------------------------------------------------- 366 * Here ends the DZ interrupt routines. 367 * ------------------------------------------------------------------- 368 */ 369 370/* 371 * This routine is used to handle the "bottom half" processing for the 372 * serial driver, known also the "software interrupt" processing. 373 * This processing is done at the kernel interrupt level, after the 374 * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This 375 * is where time-consuming activities which can not be done in the 376 * interrupt driver proper are done; the interrupt driver schedules 377 * them using rs_sched_event(), and they get done here. 378 */ 379static void do_serial_bh(void) 380{ 381 run_task_queue(&tq_serial); 382} 383 384static void do_softint(void *private_data) 385{ 386 struct dz_serial *info = (struct dz_serial *) private_data; 387 struct tty_struct *tty = info->tty; 388 389 if (!tty) 390 return; 391 392 if (test_and_clear_bit(DZ_EVENT_WRITE_WAKEUP, &info->event)) { 393 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 394 (tty->ldisc.write_wakeup) (tty); 395 wake_up_interruptible(&tty->write_wait); 396 } 397} 398 399/* 400 * ------------------------------------------------------------------- 401 * This routine is called from the scheduler tqueue when the interrupt 402 * routine has signalled that a hangup has occurred. The path of 403 * hangup processing is: 404 * 405 * serial interrupt routine -> (scheduler tqueue) -> 406 * do_serial_hangup() -> tty->hangup() -> rs_hangup() 407 * ------------------------------------------------------------------- 408 */ 409static void do_serial_hangup(void *private_data) 410{ 411 struct dz_serial *info = (struct dz_serial *) private_data; 412 struct tty_struct *tty = info->tty;; 413 414 if (!tty) 415 return; 416 417 tty_hangup(tty); 418} 419 420/* 421 * ------------------------------------------------------------------- 422 * startup () 423 * 424 * various initialization tasks 425 * ------------------------------------------------------------------- 426 */ 427static int startup(struct dz_serial *info) 428{ 429 unsigned long page, flags; 430 unsigned short tmp; 431 432 if (info->is_initialized) 433 return 0; 434 435 save_flags(flags); 436 cli(); 437 438 if (!info->port) { 439 if (info->tty) 440 set_bit(TTY_IO_ERROR, &info->tty->flags); 441 restore_flags(flags); 442 return -ENODEV; 443 } 444 if (!info->xmit_buf) { 445 page = get_free_page(GFP_KERNEL); 446 if (!page) { 447 restore_flags(flags); 448 return -ENOMEM; 449 } 450 info->xmit_buf = (unsigned char *) page; 451 } 452 if (info->tty) 453 clear_bit(TTY_IO_ERROR, &info->tty->flags); 454 455 /* enable the interrupt and the scanning */ 456 tmp = dz_in(info, DZ_CSR); 457 tmp |= (DZ_RIE | DZ_TIE | DZ_MSE); 458 dz_out(info, DZ_CSR, tmp); 459 460 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 461 462 /* set up the speed */ 463 change_speed(info); 464 465 /* clear the line transmitter buffer 466 I can't figure out why I need to do this - but 467 its necessary - in order for the console portion 468 and the interrupt portion to live happily side by side. 469 */ 470 471 /* clear the line transmitter buffer 472 I can't figure out why I need to do this - but 473 its necessary - in order for the console portion 474 and the interrupt portion to live happily side by side. 475 */ 476 477 info->is_initialized = 1; 478 479 restore_flags(flags); 480 return 0; 481} 482 483/* 484 * ------------------------------------------------------------------- 485 * shutdown () 486 * 487 * This routine will shutdown a serial port; interrupts are disabled, and 488 * DTR is dropped if the hangup on close termio flag is on. 489 * ------------------------------------------------------------------- 490 */ 491static void shutdown(struct dz_serial *info) 492{ 493 unsigned long flags; 494 unsigned short tmp; 495 496 if (!info->is_initialized) 497 return; 498 499 save_flags(flags); 500 cli(); 501 502 dz_stop(info->tty); 503 504 505 506 info->cflags &= ~DZ_CREAD; /* turn off receive enable flag */ 507 dz_out(info, DZ_LPR, info->cflags); 508 509 if (info->xmit_buf) { /* free Tx buffer */ 510 free_page((unsigned long) info->xmit_buf); 511 info->xmit_buf = 0; 512 } 513 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { 514 tmp = dz_in(info, DZ_TCR); 515 if (tmp & DZ_MODEM_DTR) { 516 tmp &= ~DZ_MODEM_DTR; 517 dz_out(info, DZ_TCR, tmp); 518 } 519 } 520 if (info->tty) 521 set_bit(TTY_IO_ERROR, &info->tty->flags); 522 523 info->is_initialized = 0; 524 restore_flags(flags); 525} 526 527/* 528 * ------------------------------------------------------------------- 529 * change_speed () 530 * 531 * set the baud rate. 532 * ------------------------------------------------------------------- 533 */ 534static void change_speed(struct dz_serial *info) 535{ 536 unsigned long flags; 537 unsigned cflag; 538 int baud; 539 540 if (!info->tty || !info->tty->termios) 541 return; 542 543 save_flags(flags); 544 cli(); 545 546 info->cflags = info->line; 547 548 cflag = info->tty->termios->c_cflag; 549 550 switch (cflag & CSIZE) { 551 case CS5: 552 info->cflags |= DZ_CS5; 553 break; 554 case CS6: 555 info->cflags |= DZ_CS6; 556 break; 557 case CS7: 558 info->cflags |= DZ_CS7; 559 break; 560 case CS8: 561 default: 562 info->cflags |= DZ_CS8; 563 } 564 565 if (cflag & CSTOPB) 566 info->cflags |= DZ_CSTOPB; 567 if (cflag & PARENB) 568 info->cflags |= DZ_PARENB; 569 if (cflag & PARODD) 570 info->cflags |= DZ_PARODD; 571 572 baud = tty_get_baud_rate(info->tty); 573 switch (baud) { 574 case 50: 575 info->cflags |= DZ_B50; 576 break; 577 case 75: 578 info->cflags |= DZ_B75; 579 break; 580 case 110: 581 info->cflags |= DZ_B110; 582 break; 583 case 134: 584 info->cflags |= DZ_B134; 585 break; 586 case 150: 587 info->cflags |= DZ_B150; 588 break; 589 case 300: 590 info->cflags |= DZ_B300; 591 break; 592 case 600: 593 info->cflags |= DZ_B600; 594 break; 595 case 1200: 596 info->cflags |= DZ_B1200; 597 break; 598 case 1800: 599 info->cflags |= DZ_B1800; 600 break; 601 case 2000: 602 info->cflags |= DZ_B2000; 603 break; 604 case 2400: 605 info->cflags |= DZ_B2400; 606 break; 607 case 3600: 608 info->cflags |= DZ_B3600; 609 break; 610 case 4800: 611 info->cflags |= DZ_B4800; 612 break; 613 case 7200: 614 info->cflags |= DZ_B7200; 615 break; 616 case 9600: 617 default: 618 info->cflags |= DZ_B9600; 619 } 620 621 info->cflags |= DZ_RXENAB; 622 dz_out(info, DZ_LPR, info->cflags); 623 624 /* setup accept flag */ 625 info->read_status_mask = DZ_OERR; 626 if (I_INPCK(info->tty)) 627 info->read_status_mask |= (DZ_FERR | DZ_PERR); 628 629 /* characters to ignore */ 630 info->ignore_status_mask = 0; 631 if (I_IGNPAR(info->tty)) 632 info->ignore_status_mask |= (DZ_FERR | DZ_PERR); 633 634 restore_flags(flags); 635} 636 637/* 638 * ------------------------------------------------------------------- 639 * dz_flush_char () 640 * 641 * Flush the buffer. 642 * ------------------------------------------------------------------- 643 */ 644static void dz_flush_chars(struct tty_struct *tty) 645{ 646 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 647 unsigned long flags; 648 649 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) 650 return; 651 652 save_flags(flags); 653 cli(); 654 655 dz_start(info->tty); 656 657 restore_flags(flags); 658} 659 660 661/* 662 * ------------------------------------------------------------------- 663 * dz_write () 664 * 665 * main output routine. 666 * ------------------------------------------------------------------- 667 */ 668static int dz_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count) 669{ 670 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 671 unsigned long flags; 672 int c, ret = 0; 673 674 if (!tty) 675 return ret; 676 if (!info->xmit_buf) 677 return ret; 678 if (!tmp_buf) 679 tmp_buf = tmp_buffer; 680 681 682 683 if (from_user) { 684 685 down(&tmp_buf_sem); 686 while (1) { 687 c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); 688 if (c <= 0) 689 break; 690 691 c -= copy_from_user(tmp_buf, buf, c); 692 if (!c) { 693 if (!ret) 694 ret = -EFAULT; 695 break; 696 } 697 save_flags(flags); 698 cli(); 699 700 c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); 701 memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); 702 info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE - 1)); 703 info->xmit_cnt += c; 704 705 restore_flags(flags); 706 707 buf += c; 708 count -= c; 709 ret += c; 710 } 711 712 up(&tmp_buf_sem); 713 } else { 714 715 716 while (1) { 717 save_flags(flags); 718 cli(); 719 720 c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head)); 721 if (c <= 0) { 722 restore_flags(flags); 723 break; 724 } 725 memcpy(info->xmit_buf + info->xmit_head, buf, c); 726 info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE - 1)); 727 info->xmit_cnt += c; 728 729 restore_flags(flags); 730 731 buf += c; 732 count -= c; 733 ret += c; 734 } 735 } 736 737 738 if (info->xmit_cnt) { 739 if (!tty->stopped) { 740 if (!tty->hw_stopped) { 741 dz_start(info->tty); 742 } 743 } 744 } 745 return ret; 746} 747 748/* 749 * ------------------------------------------------------------------- 750 * dz_write_room () 751 * 752 * compute the amount of space available for writing. 753 * ------------------------------------------------------------------- 754 */ 755static int dz_write_room(struct tty_struct *tty) 756{ 757 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 758 int ret; 759 760 ret = DZ_XMIT_SIZE - info->xmit_cnt - 1; 761 if (ret < 0) 762 ret = 0; 763 return ret; 764} 765 766/* 767 * ------------------------------------------------------------------- 768 * dz_chars_in_buffer () 769 * 770 * compute the amount of char left to be transmitted 771 * ------------------------------------------------------------------- 772 */ 773static int dz_chars_in_buffer(struct tty_struct *tty) 774{ 775 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 776 777 return info->xmit_cnt; 778} 779 780/* 781 * ------------------------------------------------------------------- 782 * dz_flush_buffer () 783 * 784 * Empty the output buffer 785 * ------------------------------------------------------------------- 786 */ 787static void dz_flush_buffer(struct tty_struct *tty) 788{ 789 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 790 791 cli(); 792 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 793 sti(); 794 795 wake_up_interruptible(&tty->write_wait); 796 797 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) 798 (tty->ldisc.write_wakeup) (tty); 799} 800 801/* 802 * ------------------------------------------------------------ 803 * dz_throttle () and dz_unthrottle () 804 * 805 * This routine is called by the upper-layer tty layer to signal that 806 * incoming characters should be throttled (or not). 807 * ------------------------------------------------------------ 808 */ 809static void dz_throttle(struct tty_struct *tty) 810{ 811 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 812 813 if (I_IXOFF(tty)) 814 info->x_char = STOP_CHAR(tty); 815} 816 817static void dz_unthrottle(struct tty_struct *tty) 818{ 819 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 820 821 if (I_IXOFF(tty)) { 822 if (info->x_char) 823 info->x_char = 0; 824 else 825 info->x_char = START_CHAR(tty); 826 } 827} 828 829static void dz_send_xchar(struct tty_struct *tty, char ch) 830{ 831 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 832 833 info->x_char = ch; 834 835 if (ch) 836 dz_start(info->tty); 837} 838 839/* 840 * ------------------------------------------------------------ 841 * rs_ioctl () and friends 842 * ------------------------------------------------------------ 843 */ 844static int get_serial_info(struct dz_serial *info, 845 struct serial_struct *retinfo) 846{ 847 struct serial_struct tmp; 848 849 if (!retinfo) 850 return -EFAULT; 851 852 memset(&tmp, 0, sizeof(tmp)); 853 854 tmp.type = info->type; 855 tmp.line = info->line; 856 tmp.port = info->port; 857 tmp.irq = dec_interrupt[DEC_IRQ_DZ11]; 858 tmp.flags = info->flags; 859 tmp.baud_base = info->baud_base; 860 tmp.close_delay = info->close_delay; 861 tmp.closing_wait = info->closing_wait; 862 863 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; 864} 865 866static int set_serial_info(struct dz_serial *info, 867 struct serial_struct *new_info) 868{ 869 struct serial_struct new_serial; 870 struct dz_serial old_info; 871 int retval = 0; 872 873 if (!new_info) 874 return -EFAULT; 875 876 if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) 877 return -EFAULT; 878 879 old_info = *info; 880 881 if (!capable(CAP_SYS_ADMIN)) 882 return -EPERM; 883 884 if (info->count > 1) 885 return -EBUSY; 886 887 /* 888 * OK, past this point, all the error checking has been done. 889 * At this point, we start making changes..... 890 */ 891 892 info->baud_base = new_serial.baud_base; 893 info->type = new_serial.type; 894 info->close_delay = new_serial.close_delay; 895 info->closing_wait = new_serial.closing_wait; 896 897 retval = startup(info); 898 return retval; 899} 900 901/* 902 * get_lsr_info - get line status register info 903 * 904 * Purpose: Let user call ioctl() to get info when the UART physically 905 * is emptied. On bus types like RS485, the transmitter must 906 * release the bus after transmitting. This must be done when 907 * the transmit shift register is empty, not be done when the 908 * transmit holding register is empty. This functionality 909 * allows an RS485 driver to be written in user space. 910 */ 911static int get_lsr_info(struct dz_serial *info, unsigned int *value) 912{ 913 unsigned short status = dz_in(info, DZ_LPR); 914 915 return put_user(status, value); 916} 917 918/* 919 * This routine sends a break character out the serial port. 920 */ 921static void send_break(struct dz_serial *info, int duration) 922{ 923 unsigned long flags; 924 unsigned short tmp, mask; 925 926 if (!info->port) 927 return; 928 929 mask = 1 << info->line; 930 tmp = dz_in(info, DZ_TCR); 931 tmp |= mask; 932 933 current->state = TASK_INTERRUPTIBLE; 934 935 save_flags(flags); 936 cli(); 937 938 dz_out(info, DZ_TCR, tmp); 939 940 schedule_timeout(duration); 941 942 tmp &= ~mask; 943 dz_out(info, DZ_TCR, tmp); 944 945 restore_flags(flags); 946} 947 948static int dz_ioctl(struct tty_struct *tty, struct file *file, 949 unsigned int cmd, unsigned long arg) 950{ 951 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 952 int retval; 953 954 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && 955 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && 956 (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { 957 if (tty->flags & (1 << TTY_IO_ERROR)) 958 return -EIO; 959 } 960 switch (cmd) { 961 case TCSBRK: /* SVID version: non-zero arg --> no break */ 962 retval = tty_check_change(tty); 963 if (retval) 964 return retval; 965 tty_wait_until_sent(tty, 0); 966 if (!arg) 967 send_break(info, HZ / 4); /* 1/4 second */ 968 return 0; 969 970 case TCSBRKP: /* support for POSIX tcsendbreak() */ 971 retval = tty_check_change(tty); 972 if (retval) 973 return retval; 974 tty_wait_until_sent(tty, 0); 975 send_break(info, arg ? arg * (HZ / 10) : HZ / 4); 976 return 0; 977 978 case TIOCGSOFTCAR: 979 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg); 980 981 case TIOCSSOFTCAR: 982 if (get_user(arg, (unsigned long *) arg)) 983 return -EFAULT; 984 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | 985 (arg ? CLOCAL : 0)); 986 return 0; 987 988 case TIOCGSERIAL: 989 return get_serial_info(info, (struct serial_struct *) arg); 990 991 case TIOCSSERIAL: 992 return set_serial_info(info, (struct serial_struct *) arg); 993 994 case TIOCSERGETLSR: /* Get line status register */ 995 return get_lsr_info(info, (unsigned int *) arg); 996 997 case TIOCSERGSTRUCT: 998 return copy_to_user((struct dz_serial *) arg, info, 999 sizeof(struct dz_serial)) ? -EFAULT : 0; 1000 1001 default: 1002 return -ENOIOCTLCMD; 1003 } 1004 1005 return 0; 1006} 1007 1008static void dz_set_termios(struct tty_struct *tty, 1009 struct termios *old_termios) 1010{ 1011 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 1012 1013 if (tty->termios->c_cflag == old_termios->c_cflag) 1014 return; 1015 1016 change_speed(info); 1017 1018 if ((old_termios->c_cflag & CRTSCTS) && 1019 !(tty->termios->c_cflag & CRTSCTS)) { 1020 tty->hw_stopped = 0; 1021 dz_start(tty); 1022 } 1023} 1024 1025/* 1026 * ------------------------------------------------------------ 1027 * dz_close() 1028 * 1029 * This routine is called when the serial port gets closed. First, we 1030 * wait for the last remaining data to be sent. Then, we turn off 1031 * the transmit enable and receive enable flags. 1032 * ------------------------------------------------------------ 1033 */ 1034static void dz_close(struct tty_struct *tty, struct file *filp) 1035{ 1036 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 1037 unsigned long flags; 1038 1039 if (!info) 1040 return; 1041 1042 save_flags(flags); 1043 cli(); 1044 1045 if (tty_hung_up_p(filp)) { 1046 restore_flags(flags); 1047 return; 1048 } 1049 if ((tty->count == 1) && (info->count != 1)) { 1050 /* 1051 * Uh, oh. tty->count is 1, which means that the tty 1052 * structure will be freed. Info->count should always 1053 * be one in these conditions. If it's greater than 1054 * one, we've got real problems, since it means the 1055 * serial port won't be shutdown. 1056 */ 1057 printk("dz_close: bad serial port count; tty->count is 1, " 1058 "info->count is %d\n", info->count); 1059 info->count = 1; 1060 } 1061 if (--info->count < 0) { 1062 printk("ds_close: bad serial port count for ttyS%02d: %d\n", 1063 info->line, info->count); 1064 info->count = 0; 1065 } 1066 if (info->count) { 1067 restore_flags(flags); 1068 return; 1069 } 1070 info->flags |= DZ_CLOSING; 1071 /* 1072 * Save the termios structure, since this port may have 1073 * separate termios for callout and dialin. 1074 */ 1075 if (info->flags & DZ_NORMAL_ACTIVE) 1076 info->normal_termios = *tty->termios; 1077 if (info->flags & DZ_CALLOUT_ACTIVE) 1078 info->callout_termios = *tty->termios; 1079 /* 1080 * Now we wait for the transmit buffer to clear; and we notify 1081 * the line discipline to only process XON/XOFF characters. 1082 */ 1083 tty->closing = 1; 1084 1085 if (info->closing_wait != DZ_CLOSING_WAIT_NONE) 1086 tty_wait_until_sent(tty, info->closing_wait); 1087 1088 /* 1089 * At this point we stop accepting input. To do this, we 1090 * disable the receive line status interrupts. 1091 */ 1092 1093 shutdown(info); 1094 1095 if (tty->driver.flush_buffer) 1096 tty->driver.flush_buffer(tty); 1097 if (tty->ldisc.flush_buffer) 1098 tty->ldisc.flush_buffer(tty); 1099 tty->closing = 0; 1100 info->event = 0; 1101 info->tty = 0; 1102 1103 if (tty->ldisc.num != ldiscs[N_TTY].num) { 1104 if (tty->ldisc.close) 1105 (tty->ldisc.close) (tty); 1106 tty->ldisc = ldiscs[N_TTY]; 1107 tty->termios->c_line = N_TTY; 1108 if (tty->ldisc.open) 1109 (tty->ldisc.open) (tty); 1110 } 1111 if (info->blocked_open) { 1112 if (info->close_delay) { 1113 current->state = TASK_INTERRUPTIBLE; 1114 schedule_timeout(info->close_delay); 1115 } 1116 wake_up_interruptible(&info->open_wait); 1117 } 1118 info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING); 1119 wake_up_interruptible(&info->close_wait); 1120 1121 restore_flags(flags); 1122} 1123 1124/* 1125 * dz_hangup () --- called by tty_hangup() when a hangup is signaled. 1126 */ 1127static void dz_hangup(struct tty_struct *tty) 1128{ 1129 struct dz_serial *info = (struct dz_serial *) tty->driver_data; 1130 1131 dz_flush_buffer(tty); 1132 shutdown(info); 1133 info->event = 0; 1134 info->count = 0; 1135 info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE); 1136 info->tty = 0; 1137 wake_up_interruptible(&info->open_wait); 1138} 1139 1140/* 1141 * ------------------------------------------------------------ 1142 * rs_open() and friends 1143 * ------------------------------------------------------------ 1144 */ 1145static int block_til_ready(struct tty_struct *tty, struct file *filp, struct dz_serial *info) 1146{ 1147 DECLARE_WAITQUEUE(wait, current); 1148 int retval; 1149 int do_clocal = 0; 1150 1151 /* 1152 * If the device is in the middle of being closed, then block 1153 * until it's done, and then try again. 1154 */ 1155 if (info->flags & DZ_CLOSING) { 1156 interruptible_sleep_on(&info->close_wait); 1157 return -EAGAIN; 1158 } 1159 /* 1160 * If this is a callout device, then just make sure the normal 1161 * device isn't being used. 1162 */ 1163 if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { 1164 if (info->flags & DZ_NORMAL_ACTIVE) 1165 return -EBUSY; 1166 1167 if ((info->flags & DZ_CALLOUT_ACTIVE) && 1168 (info->flags & DZ_SESSION_LOCKOUT) && 1169 (info->session != current->session)) 1170 return -EBUSY; 1171 1172 if ((info->flags & DZ_CALLOUT_ACTIVE) && 1173 (info->flags & DZ_PGRP_LOCKOUT) && 1174 (info->pgrp != current->pgrp)) 1175 return -EBUSY; 1176 info->flags |= DZ_CALLOUT_ACTIVE; 1177 return 0; 1178 } 1179 /* 1180 * If non-blocking mode is set, or the port is not enabled, 1181 * then make the check up front and then exit. 1182 */ 1183 if ((filp->f_flags & O_NONBLOCK) || 1184 (tty->flags & (1 << TTY_IO_ERROR))) { 1185 if (info->flags & DZ_CALLOUT_ACTIVE) 1186 return -EBUSY; 1187 info->flags |= DZ_NORMAL_ACTIVE; 1188 return 0; 1189 } 1190 if (info->flags & DZ_CALLOUT_ACTIVE) { 1191 if (info->normal_termios.c_cflag & CLOCAL) 1192 do_clocal = 1; 1193 } else { 1194 if (tty->termios->c_cflag & CLOCAL) 1195 do_clocal = 1; 1196 } 1197 1198 /* 1199 * Block waiting for the carrier detect and the line to become 1200 * free (i.e., not in use by the callout). While we are in 1201 * this loop, info->count is dropped by one, so that 1202 * dz_close() knows when to free things. We restore it upon 1203 * exit, either normal or abnormal. 1204 */ 1205 retval = 0; 1206 add_wait_queue(&info->open_wait, &wait); 1207 1208 info->count--; 1209 info->blocked_open++; 1210 while (1) { 1211 set_current_state(TASK_INTERRUPTIBLE); 1212 if (tty_hung_up_p(filp) || !(info->is_initialized)) { 1213 retval = -EAGAIN; 1214 break; 1215 } 1216 if (!(info->flags & DZ_CALLOUT_ACTIVE) && 1217 !(info->flags & DZ_CLOSING) && do_clocal) 1218 break; 1219 if (signal_pending(current)) { 1220 retval = -ERESTARTSYS; 1221 break; 1222 } 1223 schedule(); 1224 } 1225 1226 current->state = TASK_RUNNING; 1227 remove_wait_queue(&info->open_wait, &wait); 1228 if (!tty_hung_up_p(filp)) 1229 info->count++; 1230 info->blocked_open--; 1231 1232 if (retval) 1233 return retval; 1234 info->flags |= DZ_NORMAL_ACTIVE; 1235 return 0; 1236} 1237 1238/* 1239 * This routine is called whenever a serial port is opened. It 1240 * enables interrupts for a serial port. It also performs the 1241 * serial-specific initialization for the tty structure. 1242 */ 1243static int dz_open(struct tty_struct *tty, struct file *filp) 1244{ 1245 struct dz_serial *info; 1246 int retval, line; 1247 1248 line = MINOR(tty->device) - tty->driver.minor_start; 1249 1250 /* The dz lines for the mouse/keyboard must be 1251 * opened using their respective drivers. 1252 */ 1253 if ((line < 0) || (line >= DZ_NB_PORT)) 1254 return -ENODEV; 1255 1256 if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE)) 1257 return -ENODEV; 1258 1259 info = lines[line]; 1260 info->count++; 1261 1262 tty->driver_data = info; 1263 info->tty = tty; 1264 1265 /* 1266 * Start up serial port 1267 */ 1268 retval = startup(info); 1269 if (retval) 1270 return retval; 1271 1272 retval = block_til_ready(tty, filp, info); 1273 if (retval) 1274 return retval; 1275 1276 if ((info->count == 1) && (info->flags & DZ_SPLIT_TERMIOS)) { 1277 if (tty->driver.subtype == SERIAL_TYPE_NORMAL) 1278 *tty->termios = info->normal_termios; 1279 else 1280 *tty->termios = info->callout_termios; 1281 change_speed(info); 1282 1283 } 1284 info->session = current->session; 1285 info->pgrp = current->pgrp; 1286 return 0; 1287} 1288 1289static void show_serial_version(void) 1290{ 1291 printk("%s%s\n", dz_name, dz_version); 1292} 1293 1294int __init dz_init(void) 1295{ 1296 int i, tmp; 1297 long flags; 1298 struct dz_serial *info; 1299 1300 /* Setup base handler, and timer table. */ 1301 init_bh(SERIAL_BH, do_serial_bh); 1302 1303 show_serial_version(); 1304 1305 memset(&serial_driver, 0, sizeof(struct tty_driver)); 1306 serial_driver.magic = TTY_DRIVER_MAGIC; 1307#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) 1308 serial_driver.name = "ttyS"; 1309#else 1310 serial_driver.name = "tts/%d"; 1311#endif 1312 serial_driver.major = TTY_MAJOR; 1313 serial_driver.minor_start = 64; 1314 serial_driver.num = DZ_NB_PORT; 1315 serial_driver.type = TTY_DRIVER_TYPE_SERIAL; 1316 serial_driver.subtype = SERIAL_TYPE_NORMAL; 1317 serial_driver.init_termios = tty_std_termios; 1318 1319 serial_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | 1320 CLOCAL; 1321 serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; 1322 serial_driver.refcount = &serial_refcount; 1323 serial_driver.table = serial_table; 1324 serial_driver.termios = serial_termios; 1325 serial_driver.termios_locked = serial_termios_locked; 1326 1327 serial_driver.open = dz_open; 1328 serial_driver.close = dz_close; 1329 serial_driver.write = dz_write; 1330 serial_driver.flush_chars = dz_flush_chars; 1331 serial_driver.write_room = dz_write_room; 1332 serial_driver.chars_in_buffer = dz_chars_in_buffer; 1333 serial_driver.flush_buffer = dz_flush_buffer; 1334 serial_driver.ioctl = dz_ioctl; 1335 serial_driver.throttle = dz_throttle; 1336 serial_driver.unthrottle = dz_unthrottle; 1337 serial_driver.send_xchar = dz_send_xchar; 1338 serial_driver.set_termios = dz_set_termios; 1339 serial_driver.stop = dz_stop; 1340 serial_driver.start = dz_start; 1341 serial_driver.hangup = dz_hangup; 1342 1343 /* 1344 * The callout device is just like normal device except for 1345 * major number and the subtype code. 1346 */ 1347 callout_driver = serial_driver; 1348#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS)) 1349 callout_driver.name = "cua"; 1350#else 1351 callout_driver.name = "cua/%d"; 1352#endif 1353 callout_driver.major = TTYAUX_MAJOR; 1354 callout_driver.subtype = SERIAL_TYPE_CALLOUT; 1355 1356 if (tty_register_driver(&serial_driver)) 1357 panic("Couldn't register serial driver"); 1358 if (tty_register_driver(&callout_driver)) 1359 panic("Couldn't register callout driver"); 1360 save_flags(flags); 1361 cli(); 1362 1363 for (i = 0; i < DZ_NB_PORT; i++) { 1364 info = &multi[i]; 1365 lines[i] = info; 1366 info->magic = SERIAL_MAGIC; 1367 1368 if (mips_machtype == MACH_DS23100 || 1369 mips_machtype == MACH_DS5100) 1370 info->port = (unsigned long) KN01_DZ11_BASE; 1371 else 1372 info->port = (unsigned long) KN02_DZ11_BASE; 1373 1374 info->line = i; 1375 info->tty = 0; 1376 info->close_delay = 50; 1377 info->closing_wait = 3000; 1378 info->x_char = 0; 1379 info->event = 0; 1380 info->count = 0; 1381 info->blocked_open = 0; 1382 info->tqueue.routine = do_softint; 1383 info->tqueue.data = info; 1384 info->tqueue_hangup.routine = do_serial_hangup; 1385 info->tqueue_hangup.data = info; 1386 info->callout_termios = callout_driver.init_termios; 1387 info->normal_termios = serial_driver.init_termios; 1388 init_waitqueue_head(&info->open_wait); 1389 init_waitqueue_head(&info->close_wait); 1390 1391 /* 1392 * If we are pointing to address zero then punt - not correctly 1393 * set up in setup.c to handle this. 1394 */ 1395 if (!info->port) 1396 return 0; 1397 1398 printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line, 1399 info->port, dec_interrupt[DEC_IRQ_DZ11]); 1400 1401 tty_register_devfs(&serial_driver, 0, 1402 serial_driver.minor_start + info->line); 1403 tty_register_devfs(&callout_driver, 0, 1404 callout_driver.minor_start + info->line); 1405 } 1406 1407 /* reset the chip */ 1408#ifndef CONFIG_SERIAL_DEC_CONSOLE 1409 dz_out(info, DZ_CSR, DZ_CLR); 1410 while ((tmp = dz_in(info, DZ_CSR)) & DZ_CLR); 1411 iob(); 1412 1413 /* enable scanning */ 1414 dz_out(info, DZ_CSR, DZ_MSE); 1415#endif 1416 1417 /* order matters here... the trick is that flags 1418 is updated... in request_irq - to immediatedly obliterate 1419 it is unwise. */ 1420 restore_flags(flags); 1421 1422 1423 if (request_irq(dec_interrupt[DEC_IRQ_DZ11], dz_interrupt, 1424 SA_INTERRUPT, "DZ", lines[0])) 1425 panic("Unable to register DZ interrupt"); 1426 1427 return 0; 1428} 1429 1430#ifdef CONFIG_SERIAL_DEC_CONSOLE 1431static void dz_console_put_char(unsigned char ch) 1432{ 1433 unsigned long flags; 1434 int loops = 2500; 1435 unsigned short tmp = ch; 1436 /* this code sends stuff out to serial device - spinning its 1437 wheels and waiting. */ 1438 1439 /* force the issue - point it at lines[3] */ 1440 dz_console = &multi[CONSOLE_LINE]; 1441 1442 save_flags(flags); 1443 cli(); 1444 1445 1446 /* spin our wheels */ 1447 while (((dz_in(dz_console, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--); 1448 1449 /* Actually transmit the character. */ 1450 dz_out(dz_console, DZ_TDR, tmp); 1451 1452 restore_flags(flags); 1453} 1454/* 1455 * ------------------------------------------------------------------- 1456 * dz_console_print () 1457 * 1458 * dz_console_print is registered for printk. 1459 * The console must be locked when we get here. 1460 * ------------------------------------------------------------------- 1461 */ 1462static void dz_console_print(struct console *cons, 1463 const char *str, 1464 unsigned int count) 1465{ 1466#ifdef DEBUG_DZ 1467 prom_printf((char *) str); 1468#endif 1469 while (count--) { 1470 if (*str == '\n') 1471 dz_console_put_char('\r'); 1472 dz_console_put_char(*str++); 1473 } 1474} 1475 1476static kdev_t dz_console_device(struct console *c) 1477{ 1478 return MKDEV(TTY_MAJOR, 64 + c->index); 1479} 1480 1481static int __init dz_console_setup(struct console *co, char *options) 1482{ 1483 int baud = 9600; 1484 int bits = 8; 1485 int parity = 'n'; 1486 int cflag = CREAD | HUPCL | CLOCAL; 1487 char *s; 1488 unsigned short mask, tmp; 1489 1490 if (options) { 1491 baud = simple_strtoul(options, NULL, 10); 1492 s = options; 1493 while (*s >= '0' && *s <= '9') 1494 s++; 1495 if (*s) 1496 parity = *s++; 1497 if (*s) 1498 bits = *s - '0'; 1499 } 1500 /* 1501 * Now construct a cflag setting. 1502 */ 1503 switch (baud) { 1504 case 1200: 1505 cflag |= DZ_B1200; 1506 break; 1507 case 2400: 1508 cflag |= DZ_B2400; 1509 break; 1510 case 4800: 1511 cflag |= DZ_B4800; 1512 break; 1513 case 9600: 1514 default: 1515 cflag |= DZ_B9600; 1516 break; 1517 } 1518 switch (bits) { 1519 case 7: 1520 cflag |= DZ_CS7; 1521 break; 1522 default: 1523 case 8: 1524 cflag |= DZ_CS8; 1525 break; 1526 } 1527 switch (parity) { 1528 case 'o': 1529 case 'O': 1530 cflag |= DZ_PARODD; 1531 break; 1532 case 'e': 1533 case 'E': 1534 cflag |= DZ_PARENB; 1535 break; 1536 } 1537 co->cflag = cflag; 1538 1539 /* TOFIX: force to console line */ 1540 dz_console = &multi[CONSOLE_LINE]; 1541 if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) 1542 dz_console->port = KN01_DZ11_BASE; 1543 else 1544 dz_console->port = KN02_DZ11_BASE; 1545 dz_console->line = CONSOLE_LINE; 1546 1547 dz_out(dz_console, DZ_CSR, DZ_CLR); 1548 while ((tmp = dz_in(dz_console, DZ_CSR)) & DZ_CLR); 1549 1550 /* enable scanning */ 1551 dz_out(dz_console, DZ_CSR, DZ_MSE); 1552 1553 /* Set up flags... */ 1554 dz_console->cflags = 0; 1555 dz_console->cflags |= DZ_B9600; 1556 dz_console->cflags |= DZ_CS8; 1557 dz_console->cflags |= DZ_PARENB; 1558 dz_out(dz_console, DZ_LPR, dz_console->cflags); 1559 1560 mask = 1 << dz_console->line; 1561 tmp = dz_in(dz_console, DZ_TCR); /* read the TX flag */ 1562 if (!(tmp & mask)) { 1563 tmp |= mask; /* set the TX flag */ 1564 dz_out(dz_console, DZ_TCR, tmp); 1565 } 1566 return 0; 1567} 1568 1569static struct console dz_sercons = 1570{ 1571 .name = "ttyS", 1572 .write = dz_console_print, 1573 .device = dz_console_device, 1574 .setup = dz_console_setup, 1575 .flags = CON_CONSDEV | CON_PRINTBUFFER, 1576 .index = CONSOLE_LINE, 1577}; 1578 1579void __init dz_serial_console_init(void) 1580{ 1581 register_console(&dz_sercons); 1582} 1583 1584#endif /* CONFIG_SERIAL_DEC_CONSOLE */ 1585 1586MODULE_LICENSE("GPL"); 1587