1/* 2 * linux/drivers/char/serial_amba.c 3 * 4 * Driver for AMBA serial ports 5 * 6 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. 7 * 8 * Copyright 1999 ARM Limited 9 * Copyright (C) 2000 Deep Blue Solutions Ltd. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 * 25 * 26 * This is a generic driver for ARM AMBA-type serial ports. They 27 * have a lot of 16550-like features, but are not register compatable. 28 * Note that although they do have CTS, DCD and DSR inputs, they do 29 * not have an RI input, nor do they have DTR or RTS outputs. If 30 * required, these have to be supplied via some other means (eg, GPIO) 31 * and hooked into this driver. 32 * 33 * This could very easily become a generic serial driver for dumb UARTs 34 * (eg, {82,16x}50, 21285, SA1100). 35 */ 36 37#include <linux/config.h> 38#include <linux/module.h> 39#include <linux/errno.h> 40#include <linux/signal.h> 41#include <linux/sched.h> 42#include <linux/interrupt.h> 43#include <linux/tty.h> 44#include <linux/tty_flip.h> 45#include <linux/major.h> 46#include <linux/string.h> 47#include <linux/fcntl.h> 48#include <linux/ptrace.h> 49#include <linux/ioport.h> 50#include <linux/mm.h> 51#include <linux/slab.h> 52#include <linux/init.h> 53#include <linux/circ_buf.h> 54#include <linux/serial.h> 55#include <linux/console.h> 56#include <linux/sysrq.h> 57 58#include <asm/system.h> 59#include <asm/io.h> 60#include <asm/irq.h> 61#include <asm/uaccess.h> 62#include <asm/bitops.h> 63 64#include <asm/hardware/serial_amba.h> 65 66#define SERIAL_AMBA_NAME "ttyAM" 67#define SERIAL_AMBA_MAJOR 204 68#define SERIAL_AMBA_MINOR 16 69#define SERIAL_AMBA_NR 2 70 71#define CALLOUT_AMBA_NAME "cuaam" 72#define CALLOUT_AMBA_MAJOR 205 73#define CALLOUT_AMBA_MINOR 16 74#define CALLOUT_AMBA_NR SERIAL_AMBA_NR 75 76#ifndef TRUE 77#define TRUE 1 78#endif 79#ifndef FALSE 80#define FALSE 0 81#endif 82 83#define DEBUG 0 84#define DEBUG_LEDS 0 85 86#if DEBUG_LEDS 87extern int get_leds(void); 88extern int set_leds(int); 89#endif 90 91/* 92 * Access routines for the AMBA UARTs 93 */ 94#define UART_GET_INT_STATUS(p) IO_READ((p)->uart_base + AMBA_UARTIIR) 95#define UART_GET_FR(p) IO_READ((p)->uart_base + AMBA_UARTFR) 96#define UART_GET_CHAR(p) IO_READ((p)->uart_base + AMBA_UARTDR) 97#define UART_PUT_CHAR(p, c) IO_WRITE((p)->uart_base + AMBA_UARTDR, (c)) 98#define UART_GET_RSR(p) IO_READ((p)->uart_base + AMBA_UARTRSR) 99#define UART_GET_CR(p) IO_READ((p)->uart_base + AMBA_UARTCR) 100#define UART_PUT_CR(p,c) IO_WRITE((p)->uart_base + AMBA_UARTCR, (c)) 101#define UART_GET_LCRL(p) IO_READ((p)->uart_base + AMBA_UARTLCR_L) 102#define UART_PUT_LCRL(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_L, (c)) 103#define UART_GET_LCRM(p) IO_READ((p)->uart_base + AMBA_UARTLCR_M) 104#define UART_PUT_LCRM(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_M, (c)) 105#define UART_GET_LCRH(p) IO_READ((p)->uart_base + AMBA_UARTLCR_H) 106#define UART_PUT_LCRH(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_H, (c)) 107#define UART_RX_DATA(s) (((s) & AMBA_UARTFR_RXFE) == 0) 108#define UART_TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0) 109#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0) 110 111#define AMBA_UARTRSR_ANY (AMBA_UARTRSR_OE|AMBA_UARTRSR_BE|AMBA_UARTRSR_PE|AMBA_UARTRSR_FE) 112#define AMBA_UARTFR_MODEM_ANY (AMBA_UARTFR_DCD|AMBA_UARTFR_DSR|AMBA_UARTFR_CTS) 113 114/* 115 * Things needed by tty driver 116 */ 117static struct tty_driver ambanormal_driver, ambacallout_driver; 118static int ambauart_refcount; 119static struct tty_struct *ambauart_table[SERIAL_AMBA_NR]; 120static struct termios *ambauart_termios[SERIAL_AMBA_NR]; 121static struct termios *ambauart_termios_locked[SERIAL_AMBA_NR]; 122 123#if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 124#define SUPPORT_SYSRQ 125#endif 126 127/* 128 * Things needed internally to this driver 129 */ 130 131/* 132 * tmp_buf is used as a temporary buffer by serial_write. We need to 133 * lock it in case the copy_from_user blocks while swapping in a page, 134 * and some other program tries to do a serial write at the same time. 135 * Since the lock will only come under contention when the system is 136 * swapping and available memory is low, it makes sense to share one 137 * buffer across all the serial ports, since it significantly saves 138 * memory if large numbers of serial ports are open. 139 */ 140static u_char *tmp_buf; 141static DECLARE_MUTEX(tmp_buf_sem); 142 143#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 144 145/* number of characters left in xmit buffer before we ask for more */ 146#define WAKEUP_CHARS 256 147#define AMBA_ISR_PASS_LIMIT 256 148 149#define EVT_WRITE_WAKEUP 0 150 151struct amba_icount { 152 __u32 cts; 153 __u32 dsr; 154 __u32 rng; 155 __u32 dcd; 156 __u32 rx; 157 __u32 tx; 158 __u32 frame; 159 __u32 overrun; 160 __u32 parity; 161 __u32 brk; 162 __u32 buf_overrun; 163}; 164 165/* 166 * Static information about the port 167 */ 168struct amba_port { 169 unsigned int uart_base; 170 unsigned int irq; 171 unsigned int uartclk; 172 unsigned int fifosize; 173 unsigned int tiocm_support; 174 void (*set_mctrl)(struct amba_port *, u_int mctrl); 175}; 176 177/* 178 * This is the state information which is persistent across opens 179 */ 180struct amba_state { 181 struct amba_icount icount; 182 unsigned int line; 183 unsigned int close_delay; 184 unsigned int closing_wait; 185 unsigned int custom_divisor; 186 unsigned int flags; 187 struct termios normal_termios; 188 struct termios callout_termios; 189 190 int count; 191 struct amba_info *info; 192}; 193 194#define AMBA_XMIT_SIZE 1024 195/* 196 * This is the state information which is only valid when the port is open. 197 */ 198struct amba_info { 199 struct amba_port *port; 200 struct amba_state *state; 201 struct tty_struct *tty; 202 unsigned char x_char; 203 unsigned char old_status; 204 unsigned char read_status_mask; 205 unsigned char ignore_status_mask; 206 struct circ_buf xmit; 207 unsigned int flags; 208#ifdef SUPPORT_SYSRQ 209 unsigned long sysrq; 210#endif 211 212 unsigned int event; 213 unsigned int timeout; 214 unsigned int lcr_h; 215 unsigned int mctrl; 216 int blocked_open; 217 pid_t session; 218 pid_t pgrp; 219 220 struct tasklet_struct tlet; 221 222 wait_queue_head_t open_wait; 223 wait_queue_head_t close_wait; 224 wait_queue_head_t delta_msr_wait; 225}; 226 227#ifdef CONFIG_SERIAL_AMBA_CONSOLE 228static struct console ambauart_cons; 229#endif 230static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios); 231static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout); 232 233static void amba_set_mctrl_null(struct amba_port *port, u_int mctrl) 234{ 235} 236 237static struct amba_port amba_ports[SERIAL_AMBA_NR] = { 238 { 239 uart_base: IO_ADDRESS(INTEGRATOR_UART0_BASE), 240 irq: IRQ_UARTINT0, 241 uartclk: 14745600, 242 fifosize: 8, 243 set_mctrl: amba_set_mctrl_null, 244 }, 245 { 246 uart_base: IO_ADDRESS(INTEGRATOR_UART1_BASE), 247 irq: IRQ_UARTINT1, 248 uartclk: 14745600, 249 fifosize: 8, 250 set_mctrl: amba_set_mctrl_null, 251 } 252}; 253 254static struct amba_state amba_state[SERIAL_AMBA_NR]; 255 256static void ambauart_enable_rx_interrupt(struct amba_info *info) 257{ 258 unsigned int cr; 259 260 cr = UART_GET_CR(info->port); 261 cr |= AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE; 262 UART_PUT_CR(info->port, cr); 263} 264 265static void ambauart_disable_rx_interrupt(struct amba_info *info) 266{ 267 unsigned int cr; 268 269 cr = UART_GET_CR(info->port); 270 cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE); 271 UART_PUT_CR(info->port, cr); 272} 273 274static void ambauart_enable_tx_interrupt(struct amba_info *info) 275{ 276 unsigned int cr; 277 278 cr = UART_GET_CR(info->port); 279 cr |= AMBA_UARTCR_TIE; 280 UART_PUT_CR(info->port, cr); 281} 282 283static void ambauart_disable_tx_interrupt(struct amba_info *info) 284{ 285 unsigned int cr; 286 287 cr = UART_GET_CR(info->port); 288 cr &= ~AMBA_UARTCR_TIE; 289 UART_PUT_CR(info->port, cr); 290} 291 292static void ambauart_stop(struct tty_struct *tty) 293{ 294 struct amba_info *info = tty->driver_data; 295 unsigned long flags; 296 297 save_flags(flags); cli(); 298 ambauart_disable_tx_interrupt(info); 299 restore_flags(flags); 300} 301 302static void ambauart_start(struct tty_struct *tty) 303{ 304 struct amba_info *info = tty->driver_data; 305 unsigned long flags; 306 307 save_flags(flags); cli(); 308 if (info->xmit.head != info->xmit.tail 309 && info->xmit.buf) 310 ambauart_enable_tx_interrupt(info); 311 restore_flags(flags); 312} 313 314 315/* 316 * This routine is used by the interrupt handler to schedule 317 * processing in the software interrupt portion of the driver. 318 */ 319static void ambauart_event(struct amba_info *info, int event) 320{ 321 info->event |= 1 << event; 322 tasklet_schedule(&info->tlet); 323} 324 325static void 326#ifdef SUPPORT_SYSRQ 327ambauart_rx_chars(struct amba_info *info, struct pt_regs *regs) 328#else 329ambauart_rx_chars(struct amba_info *info) 330#endif 331{ 332 struct tty_struct *tty = info->tty; 333 unsigned int status, ch, rsr, flg, ignored = 0; 334 struct amba_icount *icount = &info->state->icount; 335 struct amba_port *port = info->port; 336 337 status = UART_GET_FR(port); 338 while (UART_RX_DATA(status)) { 339 ch = UART_GET_CHAR(port); 340 341 if (tty->flip.count >= TTY_FLIPBUF_SIZE) 342 goto ignore_char; 343 icount->rx++; 344 345 flg = TTY_NORMAL; 346 347 /* 348 * Note that the error handling code is 349 * out of the main execution path 350 */ 351 rsr = UART_GET_RSR(port); 352 if (rsr & AMBA_UARTRSR_ANY) 353 goto handle_error; 354#ifdef SUPPORT_SYSRQ 355 if (info->sysrq) { 356 if (ch && time_before(jiffies, info->sysrq)) { 357 handle_sysrq(ch, regs, NULL, NULL); 358 info->sysrq = 0; 359 goto ignore_char; 360 } 361 info->sysrq = 0; 362 } 363#endif 364 error_return: 365 *tty->flip.flag_buf_ptr++ = flg; 366 *tty->flip.char_buf_ptr++ = ch; 367 tty->flip.count++; 368 ignore_char: 369 status = UART_GET_FR(port); 370 } 371out: 372 tty_flip_buffer_push(tty); 373 return; 374 375handle_error: 376 if (rsr & AMBA_UARTRSR_BE) { 377 rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE); 378 icount->brk++; 379 380#ifdef SUPPORT_SYSRQ 381 if (info->state->line == ambauart_cons.index) { 382 if (!info->sysrq) { 383 info->sysrq = jiffies + HZ*5; 384 goto ignore_char; 385 } 386 } 387#endif 388 } else if (rsr & AMBA_UARTRSR_PE) 389 icount->parity++; 390 else if (rsr & AMBA_UARTRSR_FE) 391 icount->frame++; 392 if (rsr & AMBA_UARTRSR_OE) 393 icount->overrun++; 394 395 if (rsr & info->ignore_status_mask) { 396 if (++ignored > 100) 397 goto out; 398 goto ignore_char; 399 } 400 rsr &= info->read_status_mask; 401 402 if (rsr & AMBA_UARTRSR_BE) 403 flg = TTY_BREAK; 404 else if (rsr & AMBA_UARTRSR_PE) 405 flg = TTY_PARITY; 406 else if (rsr & AMBA_UARTRSR_FE) 407 flg = TTY_FRAME; 408 409 if (rsr & AMBA_UARTRSR_OE) { 410 /* 411 * CHECK: does overrun affect the current character? 412 * ASSUMPTION: it does not. 413 */ 414 *tty->flip.flag_buf_ptr++ = flg; 415 *tty->flip.char_buf_ptr++ = ch; 416 tty->flip.count++; 417 if (tty->flip.count >= TTY_FLIPBUF_SIZE) 418 goto ignore_char; 419 ch = 0; 420 flg = TTY_OVERRUN; 421 } 422#ifdef SUPPORT_SYSRQ 423 info->sysrq = 0; 424#endif 425 goto error_return; 426} 427 428static void ambauart_tx_chars(struct amba_info *info) 429{ 430 struct amba_port *port = info->port; 431 int count; 432 433 if (info->x_char) { 434 UART_PUT_CHAR(port, info->x_char); 435 info->state->icount.tx++; 436 info->x_char = 0; 437 return; 438 } 439 if (info->xmit.head == info->xmit.tail 440 || info->tty->stopped 441 || info->tty->hw_stopped) { 442 ambauart_disable_tx_interrupt(info); 443 return; 444 } 445 446 count = port->fifosize; 447 do { 448 UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]); 449 info->xmit.tail = (info->xmit.tail + 1) & (AMBA_XMIT_SIZE - 1); 450 info->state->icount.tx++; 451 if (info->xmit.head == info->xmit.tail) 452 break; 453 } while (--count > 0); 454 455 if (CIRC_CNT(info->xmit.head, 456 info->xmit.tail, 457 AMBA_XMIT_SIZE) < WAKEUP_CHARS) 458 ambauart_event(info, EVT_WRITE_WAKEUP); 459 460 if (info->xmit.head == info->xmit.tail) { 461 ambauart_disable_tx_interrupt(info); 462 } 463} 464 465static void ambauart_modem_status(struct amba_info *info) 466{ 467 unsigned int status, delta; 468 struct amba_icount *icount = &info->state->icount; 469 470 status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY; 471 472 delta = status ^ info->old_status; 473 info->old_status = status; 474 475 if (!delta) 476 return; 477 478 if (delta & AMBA_UARTFR_DCD) { 479 icount->dcd++; 480#ifdef CONFIG_HARD_PPS 481 if ((info->flags & ASYNC_HARDPPS_CD) && 482 (status & AMBA_UARTFR_DCD) 483 hardpps(); 484#endif 485 if (info->flags & ASYNC_CHECK_CD) { 486 if (status & AMBA_UARTFR_DCD) 487 wake_up_interruptible(&info->open_wait); 488 else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && 489 (info->flags & ASYNC_CALLOUT_NOHUP))) { 490 if (info->tty) 491 tty_hangup(info->tty); 492 } 493 } 494 } 495 496 if (delta & AMBA_UARTFR_DSR) 497 icount->dsr++; 498 499 if (delta & AMBA_UARTFR_CTS) { 500 icount->cts++; 501 502 if (info->flags & ASYNC_CTS_FLOW) { 503 status &= AMBA_UARTFR_CTS; 504 505 if (info->tty->hw_stopped) { 506 if (status) { 507 info->tty->hw_stopped = 0; 508 ambauart_enable_tx_interrupt(info); 509 ambauart_event(info, EVT_WRITE_WAKEUP); 510 } 511 } else { 512 if (!status) { 513 info->tty->hw_stopped = 1; 514 ambauart_disable_tx_interrupt(info); 515 } 516 } 517 } 518 } 519 wake_up_interruptible(&info->delta_msr_wait); 520 521} 522 523static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs) 524{ 525 struct amba_info *info = dev_id; 526 unsigned int status, pass_counter = 0; 527 528#if DEBUG_LEDS 529 // tell the world 530 set_leds(get_leds() | RED_LED); 531#endif 532 533 status = UART_GET_INT_STATUS(info->port); 534 do { 535 536 if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS)) 537#ifdef SUPPORT_SYSRQ 538 ambauart_rx_chars(info, regs); 539#else 540 ambauart_rx_chars(info); 541#endif 542 if (status & AMBA_UARTIIR_TIS) 543 ambauart_tx_chars(info); 544 if (status & AMBA_UARTIIR_MIS) 545 ambauart_modem_status(info); 546 if (pass_counter++ > AMBA_ISR_PASS_LIMIT) 547 break; 548 549 status = UART_GET_INT_STATUS(info->port); 550 } while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS | AMBA_UARTIIR_TIS)); 551 552#if DEBUG_LEDS 553 // tell the world 554 set_leds(get_leds() & ~RED_LED); 555#endif 556} 557 558static void ambauart_tasklet_action(unsigned long data) 559{ 560 struct amba_info *info = (struct amba_info *)data; 561 struct tty_struct *tty; 562 563 tty = info->tty; 564 if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event)) 565 return; 566 567 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 568 tty->ldisc.write_wakeup) 569 (tty->ldisc.write_wakeup)(tty); 570 wake_up_interruptible(&tty->write_wait); 571} 572 573static int ambauart_startup(struct amba_info *info) 574{ 575 unsigned long flags; 576 unsigned long page; 577 int retval = 0; 578 579 page = get_zeroed_page(GFP_KERNEL); 580 if (!page) 581 return -ENOMEM; 582 583 save_flags(flags); cli(); 584 585 if (info->flags & ASYNC_INITIALIZED) { 586 free_page(page); 587 goto errout; 588 } 589 590 if (info->xmit.buf) 591 free_page(page); 592 else 593 info->xmit.buf = (unsigned char *) page; 594 595 /* 596 * Allocate the IRQ 597 */ 598 retval = request_irq(info->port->irq, ambauart_int, 0, "amba", info); 599 if (retval) { 600 if (capable(CAP_SYS_ADMIN)) { 601 if (info->tty) 602 set_bit(TTY_IO_ERROR, &info->tty->flags); 603 retval = 0; 604 } 605 goto errout; 606 } 607 608 info->mctrl = 0; 609 if (info->tty->termios->c_cflag & CBAUD) 610 info->mctrl = TIOCM_RTS | TIOCM_DTR; 611 info->port->set_mctrl(info->port, info->mctrl); 612 613 /* 614 * initialise the old status of the modem signals 615 */ 616 info->old_status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY; 617 618 /* 619 * Finally, enable interrupts 620 */ 621 ambauart_enable_rx_interrupt(info); 622 623 if (info->tty) 624 clear_bit(TTY_IO_ERROR, &info->tty->flags); 625 info->xmit.head = info->xmit.tail = 0; 626 627 /* 628 * Set up the tty->alt_speed kludge 629 */ 630 if (info->tty) { 631 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 632 info->tty->alt_speed = 57600; 633 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 634 info->tty->alt_speed = 115200; 635 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 636 info->tty->alt_speed = 230400; 637 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 638 info->tty->alt_speed = 460800; 639 } 640 641 /* 642 * and set the speed of the serial port 643 */ 644 ambauart_change_speed(info, 0); 645 646 info->flags |= ASYNC_INITIALIZED; 647 restore_flags(flags); 648 return 0; 649 650errout: 651 restore_flags(flags); 652 return retval; 653} 654 655/* 656 * This routine will shutdown a serial port; interrupts are disabled, and 657 * DTR is dropped if the hangup on close termio flag is on. 658 */ 659static void ambauart_shutdown(struct amba_info *info) 660{ 661 unsigned long flags; 662 663 if (!(info->flags & ASYNC_INITIALIZED)) 664 return; 665 666 save_flags(flags); cli(); /* Disable interrupts */ 667 668 /* 669 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq 670 * here so the queue might never be woken up 671 */ 672 wake_up_interruptible(&info->delta_msr_wait); 673 674 /* 675 * Free the IRQ 676 */ 677 free_irq(info->port->irq, info); 678 679 if (info->xmit.buf) { 680 unsigned long pg = (unsigned long) info->xmit.buf; 681 info->xmit.buf = NULL; 682 free_page(pg); 683 } 684 685 /* 686 * disable all interrupts, disable the port 687 */ 688 UART_PUT_CR(info->port, 0); 689 690 /* disable break condition and fifos */ 691 UART_PUT_LCRH(info->port, UART_GET_LCRH(info->port) & 692 ~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN)); 693 694 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) 695 info->mctrl &= ~(TIOCM_DTR|TIOCM_RTS); 696 info->port->set_mctrl(info->port, info->mctrl); 697 698 /* kill off our tasklet */ 699 tasklet_kill(&info->tlet); 700 if (info->tty) 701 set_bit(TTY_IO_ERROR, &info->tty->flags); 702 703 info->flags &= ~ASYNC_INITIALIZED; 704 restore_flags(flags); 705} 706 707static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios) 708{ 709 unsigned int lcr_h, baud, quot, cflag, old_cr, bits; 710 unsigned long flags; 711 712 if (!info->tty || !info->tty->termios) 713 return; 714 715 cflag = info->tty->termios->c_cflag; 716 717#if DEBUG 718 printk("ambauart_set_cflag(0x%x) called\n", cflag); 719#endif 720 /* byte size and parity */ 721 switch (cflag & CSIZE) { 722 case CS5: lcr_h = AMBA_UARTLCR_H_WLEN_5; bits = 7; break; 723 case CS6: lcr_h = AMBA_UARTLCR_H_WLEN_6; bits = 8; break; 724 case CS7: lcr_h = AMBA_UARTLCR_H_WLEN_7; bits = 9; break; 725 default: lcr_h = AMBA_UARTLCR_H_WLEN_8; bits = 10; break; // CS8 726 } 727 if (cflag & CSTOPB) { 728 lcr_h |= AMBA_UARTLCR_H_STP2; 729 bits ++; 730 } 731 if (cflag & PARENB) { 732 lcr_h |= AMBA_UARTLCR_H_PEN; 733 bits++; 734 if (!(cflag & PARODD)) 735 lcr_h |= AMBA_UARTLCR_H_EPS; 736 } 737 if (info->port->fifosize > 1) 738 lcr_h |= AMBA_UARTLCR_H_FEN; 739 740 do { 741 /* Determine divisor based on baud rate */ 742 baud = tty_get_baud_rate(info->tty); 743 if (!baud) 744 baud = 9600; 745 746 if (baud == 38400 && 747 ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) 748 quot = info->state->custom_divisor; 749 else 750 quot = (info->port->uartclk / (16 * baud)) - 1; 751 752 if (!quot && old_termios) { 753 info->tty->termios->c_cflag &= ~CBAUD; 754 info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); 755 old_termios = NULL; 756 } 757 } while (quot == 0 && old_termios); 758 759 /* As a last resort, if the quotient is zero, default to 9600 bps */ 760 if (!quot) 761 quot = (info->port->uartclk / (16 * 9600)) - 1; 762 763 info->timeout = (info->port->fifosize * HZ * bits * quot) / 764 (info->port->uartclk / 16); 765 info->timeout += HZ/50; /* Add .02 seconds of slop */ 766 767 if (cflag & CRTSCTS) 768 info->flags |= ASYNC_CTS_FLOW; 769 else 770 info->flags &= ~ASYNC_CTS_FLOW; 771 if (cflag & CLOCAL) 772 info->flags &= ~ASYNC_CHECK_CD; 773 else 774 info->flags |= ASYNC_CHECK_CD; 775 776 /* 777 * Set up parity check flag 778 */ 779#define RELEVENT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) 780 781 info->read_status_mask = AMBA_UARTRSR_OE; 782 if (I_INPCK(info->tty)) 783 info->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE; 784 if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 785 info->read_status_mask |= AMBA_UARTRSR_BE; 786 787 /* 788 * Characters to ignore 789 */ 790 info->ignore_status_mask = 0; 791 if (I_IGNPAR(info->tty)) 792 info->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE; 793 if (I_IGNBRK(info->tty)) { 794 info->ignore_status_mask |= AMBA_UARTRSR_BE; 795 /* 796 * If we're ignoring parity and break indicators, 797 * ignore overruns to (for real raw support). 798 */ 799 if (I_IGNPAR(info->tty)) 800 info->ignore_status_mask |= AMBA_UARTRSR_OE; 801 } 802 803 /* first, disable everything */ 804 save_flags(flags); cli(); 805 old_cr = UART_GET_CR(info->port) &= ~AMBA_UARTCR_MSIE; 806 807 if ((info->flags & ASYNC_HARDPPS_CD) || 808 (cflag & CRTSCTS) || 809 !(cflag & CLOCAL)) 810 old_cr |= AMBA_UARTCR_MSIE; 811 812 UART_PUT_CR(info->port, 0); 813 restore_flags(flags); 814 815 /* Set baud rate */ 816 UART_PUT_LCRM(info->port, ((quot & 0xf00) >> 8)); 817 UART_PUT_LCRL(info->port, (quot & 0xff)); 818 819 /* 820 * ----------v----------v----------v----------v----- 821 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L 822 * ----------^----------^----------^----------^----- 823 */ 824 UART_PUT_LCRH(info->port, lcr_h); 825 UART_PUT_CR(info->port, old_cr); 826} 827 828static void ambauart_put_char(struct tty_struct *tty, u_char ch) 829{ 830 struct amba_info *info = tty->driver_data; 831 unsigned long flags; 832 833 if (!tty || !info->xmit.buf) 834 return; 835 836 save_flags(flags); cli(); 837 if (CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE) != 0) { 838 info->xmit.buf[info->xmit.head] = ch; 839 info->xmit.head = (info->xmit.head + 1) & (AMBA_XMIT_SIZE - 1); 840 } 841 restore_flags(flags); 842} 843 844static void ambauart_flush_chars(struct tty_struct *tty) 845{ 846 struct amba_info *info = tty->driver_data; 847 unsigned long flags; 848 849 if (info->xmit.head == info->xmit.tail 850 || tty->stopped 851 || tty->hw_stopped 852 || !info->xmit.buf) 853 return; 854 855 save_flags(flags); cli(); 856 ambauart_enable_tx_interrupt(info); 857 restore_flags(flags); 858} 859 860static int ambauart_write(struct tty_struct *tty, int from_user, 861 const u_char * buf, int count) 862{ 863 struct amba_info *info = tty->driver_data; 864 unsigned long flags; 865 int c, ret = 0; 866 867 if (!tty || !info->xmit.buf || !tmp_buf) 868 return 0; 869 870 save_flags(flags); 871 if (from_user) { 872 down(&tmp_buf_sem); 873 while (1) { 874 int c1; 875 c = CIRC_SPACE_TO_END(info->xmit.head, 876 info->xmit.tail, 877 AMBA_XMIT_SIZE); 878 if (count < c) 879 c = count; 880 if (c <= 0) 881 break; 882 883 c -= copy_from_user(tmp_buf, buf, c); 884 if (!c) { 885 if (!ret) 886 ret = -EFAULT; 887 break; 888 } 889 cli(); 890 c1 = CIRC_SPACE_TO_END(info->xmit.head, 891 info->xmit.tail, 892 AMBA_XMIT_SIZE); 893 if (c1 < c) 894 c = c1; 895 memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); 896 info->xmit.head = (info->xmit.head + c) & 897 (AMBA_XMIT_SIZE - 1); 898 restore_flags(flags); 899 buf += c; 900 count -= c; 901 ret += c; 902 } 903 up(&tmp_buf_sem); 904 } else { 905 cli(); 906 while (1) { 907 c = CIRC_SPACE_TO_END(info->xmit.head, 908 info->xmit.tail, 909 AMBA_XMIT_SIZE); 910 if (count < c) 911 c = count; 912 if (c <= 0) 913 break; 914 memcpy(info->xmit.buf + info->xmit.head, buf, c); 915 info->xmit.head = (info->xmit.head + c) & 916 (AMBA_XMIT_SIZE - 1); 917 buf += c; 918 count -= c; 919 ret += c; 920 } 921 restore_flags(flags); 922 } 923 if (info->xmit.head != info->xmit.tail 924 && !tty->stopped 925 && !tty->hw_stopped) 926 ambauart_enable_tx_interrupt(info); 927 return ret; 928} 929 930static int ambauart_write_room(struct tty_struct *tty) 931{ 932 struct amba_info *info = tty->driver_data; 933 934 return CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE); 935} 936 937static int ambauart_chars_in_buffer(struct tty_struct *tty) 938{ 939 struct amba_info *info = tty->driver_data; 940 941 return CIRC_CNT(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE); 942} 943 944static void ambauart_flush_buffer(struct tty_struct *tty) 945{ 946 struct amba_info *info = tty->driver_data; 947 unsigned long flags; 948 949#if DEBUG 950 printk("ambauart_flush_buffer(%d) called\n", 951 MINOR(tty->device) - tty->driver.minor_start); 952#endif 953 save_flags(flags); cli(); 954 info->xmit.head = info->xmit.tail = 0; 955 restore_flags(flags); 956 wake_up_interruptible(&tty->write_wait); 957 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 958 tty->ldisc.write_wakeup) 959 (tty->ldisc.write_wakeup)(tty); 960} 961 962/* 963 * This function is used to send a high-priority XON/XOFF character to 964 * the device 965 */ 966static void ambauart_send_xchar(struct tty_struct *tty, char ch) 967{ 968 struct amba_info *info = tty->driver_data; 969 970 info->x_char = ch; 971 if (ch) 972 ambauart_enable_tx_interrupt(info); 973} 974 975static void ambauart_throttle(struct tty_struct *tty) 976{ 977 struct amba_info *info = tty->driver_data; 978 unsigned long flags; 979 980 if (I_IXOFF(tty)) 981 ambauart_send_xchar(tty, STOP_CHAR(tty)); 982 983 if (tty->termios->c_cflag & CRTSCTS) { 984 save_flags(flags); cli(); 985 info->mctrl &= ~TIOCM_RTS; 986 info->port->set_mctrl(info->port, info->mctrl); 987 restore_flags(flags); 988 } 989} 990 991static void ambauart_unthrottle(struct tty_struct *tty) 992{ 993 struct amba_info *info = (struct amba_info *) tty->driver_data; 994 unsigned long flags; 995 996 if (I_IXOFF(tty)) { 997 if (info->x_char) 998 info->x_char = 0; 999 else 1000 ambauart_send_xchar(tty, START_CHAR(tty)); 1001 } 1002 1003 if (tty->termios->c_cflag & CRTSCTS) { 1004 save_flags(flags); cli(); 1005 info->mctrl |= TIOCM_RTS; 1006 info->port->set_mctrl(info->port, info->mctrl); 1007 restore_flags(flags); 1008 } 1009} 1010 1011static int get_serial_info(struct amba_info *info, struct serial_struct *retinfo) 1012{ 1013 struct amba_state *state = info->state; 1014 struct amba_port *port = info->port; 1015 struct serial_struct tmp; 1016 1017 memset(&tmp, 0, sizeof(tmp)); 1018 tmp.type = 0; 1019 tmp.line = state->line; 1020 tmp.port = port->uart_base; 1021 if (HIGH_BITS_OFFSET) 1022 tmp.port_high = port->uart_base >> HIGH_BITS_OFFSET; 1023 tmp.irq = port->irq; 1024 tmp.flags = 0; 1025 tmp.xmit_fifo_size = port->fifosize; 1026 tmp.baud_base = port->uartclk / 16; 1027 tmp.close_delay = state->close_delay; 1028 tmp.closing_wait = state->closing_wait; 1029 tmp.custom_divisor = state->custom_divisor; 1030 1031 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 1032 return -EFAULT; 1033 return 0; 1034} 1035 1036static int set_serial_info(struct amba_info *info, 1037 struct serial_struct *newinfo) 1038{ 1039 struct serial_struct new_serial; 1040 struct amba_state *state, old_state; 1041 struct amba_port *port; 1042 unsigned long new_port; 1043 unsigned int i, change_irq, change_port; 1044 int retval = 0; 1045 1046 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) 1047 return -EFAULT; 1048 1049 state = info->state; 1050 old_state = *state; 1051 port = info->port; 1052 1053 new_port = new_serial.port; 1054 if (HIGH_BITS_OFFSET) 1055 new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; 1056 1057 change_irq = new_serial.irq != port->irq; 1058 change_port = new_port != port->uart_base; 1059 1060 if (!capable(CAP_SYS_ADMIN)) { 1061 if (change_irq || change_port || 1062 (new_serial.baud_base != port->uartclk / 16) || 1063 (new_serial.close_delay != state->close_delay) || 1064 (new_serial.xmit_fifo_size != port->fifosize) || 1065 ((new_serial.flags & ~ASYNC_USR_MASK) != 1066 (state->flags & ~ASYNC_USR_MASK))) 1067 return -EPERM; 1068 state->flags = ((state->flags & ~ASYNC_USR_MASK) | 1069 (new_serial.flags & ASYNC_USR_MASK)); 1070 info->flags = ((info->flags & ~ASYNC_USR_MASK) | 1071 (new_serial.flags & ASYNC_USR_MASK)); 1072 state->custom_divisor = new_serial.custom_divisor; 1073 goto check_and_exit; 1074 } 1075 1076 if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 1077 (new_serial.baud_base < 9600)) 1078 return -EINVAL; 1079 1080 if (new_serial.type && change_port) { 1081 for (i = 0; i < SERIAL_AMBA_NR; i++) 1082 if ((port != amba_ports + i) && 1083 amba_ports[i].uart_base != new_port) 1084 return -EADDRINUSE; 1085 } 1086 1087 if ((change_port || change_irq) && (state->count > 1)) 1088 return -EBUSY; 1089 1090 /* 1091 * OK, past this point, all the error checking has been done. 1092 * At this point, we start making changes..... 1093 */ 1094 port->uartclk = new_serial.baud_base * 16; 1095 state->flags = ((state->flags & ~ASYNC_FLAGS) | 1096 (new_serial.flags & ASYNC_FLAGS)); 1097 info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | 1098 (info->flags & ASYNC_INTERNAL_FLAGS)); 1099 state->custom_divisor = new_serial.custom_divisor; 1100 state->close_delay = new_serial.close_delay * HZ / 100; 1101 state->closing_wait = new_serial.closing_wait * HZ / 100; 1102 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1103 port->fifosize = new_serial.xmit_fifo_size; 1104 1105 if (change_port || change_irq) { 1106 /* 1107 * We need to shutdown the serial port at the old 1108 * port/irq combination. 1109 */ 1110 ambauart_shutdown(info); 1111 port->irq = new_serial.irq; 1112 port->uart_base = new_port; 1113 } 1114 1115check_and_exit: 1116 if (!port->uart_base) 1117 return 0; 1118 if (info->flags & ASYNC_INITIALIZED) { 1119 if ((old_state.flags & ASYNC_SPD_MASK) != 1120 (state->flags & ASYNC_SPD_MASK) || 1121 (old_state.custom_divisor != state->custom_divisor)) { 1122 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 1123 info->tty->alt_speed = 57600; 1124 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 1125 info->tty->alt_speed = 115200; 1126 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 1127 info->tty->alt_speed = 230400; 1128 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 1129 info->tty->alt_speed = 460800; 1130 ambauart_change_speed(info, NULL); 1131 } 1132 } else 1133 retval = ambauart_startup(info); 1134 return retval; 1135} 1136 1137 1138/* 1139 * get_lsr_info - get line status register info 1140 */ 1141static int get_lsr_info(struct amba_info *info, unsigned int *value) 1142{ 1143 unsigned int result, status; 1144 unsigned long flags; 1145 1146 save_flags(flags); cli(); 1147 status = UART_GET_FR(info->port); 1148 restore_flags(flags); 1149 result = status & AMBA_UARTFR_BUSY ? TIOCSER_TEMT : 0; 1150 1151 /* 1152 * If we're about to load something into the transmit 1153 * register, we'll pretend the transmitter isn't empty to 1154 * avoid a race condition (depending on when the transmit 1155 * interrupt happens). 1156 */ 1157 if (info->x_char || 1158 ((CIRC_CNT(info->xmit.head, info->xmit.tail, 1159 AMBA_XMIT_SIZE) > 0) && 1160 !info->tty->stopped && !info->tty->hw_stopped)) 1161 result &= TIOCSER_TEMT; 1162 1163 return put_user(result, value); 1164} 1165 1166static int get_modem_info(struct amba_info *info, unsigned int *value) 1167{ 1168 unsigned int result = info->mctrl; 1169 unsigned int status; 1170 1171 status = UART_GET_FR(info->port); 1172 if (status & AMBA_UARTFR_DCD) 1173 result |= TIOCM_CAR; 1174 if (status & AMBA_UARTFR_DSR) 1175 result |= TIOCM_DSR; 1176 if (status & AMBA_UARTFR_CTS) 1177 result |= TIOCM_CTS; 1178 1179 return put_user(result, value); 1180} 1181 1182static int set_modem_info(struct amba_info *info, unsigned int cmd, 1183 unsigned int *value) 1184{ 1185 unsigned int arg, old; 1186 unsigned long flags; 1187 1188 if (get_user(arg, value)) 1189 return -EFAULT; 1190 1191 old = info->mctrl; 1192 switch (cmd) { 1193 case TIOCMBIS: 1194 info->mctrl |= arg; 1195 break; 1196 1197 case TIOCMBIC: 1198 info->mctrl &= ~arg; 1199 break; 1200 1201 case TIOCMSET: 1202 info->mctrl = arg; 1203 break; 1204 1205 default: 1206 return -EINVAL; 1207 } 1208 save_flags(flags); cli(); 1209 if (old != info->mctrl) 1210 info->port->set_mctrl(info->port, info->mctrl); 1211 restore_flags(flags); 1212 return 0; 1213} 1214 1215static void ambauart_break_ctl(struct tty_struct *tty, int break_state) 1216{ 1217 struct amba_info *info = tty->driver_data; 1218 unsigned long flags; 1219 unsigned int lcr_h; 1220 1221 save_flags(flags); cli(); 1222 lcr_h = UART_GET_LCRH(info->port); 1223 if (break_state == -1) 1224 lcr_h |= AMBA_UARTLCR_H_BRK; 1225 else 1226 lcr_h &= ~AMBA_UARTLCR_H_BRK; 1227 UART_PUT_LCRH(info->port, lcr_h); 1228 restore_flags(flags); 1229} 1230 1231static int ambauart_ioctl(struct tty_struct *tty, struct file *file, 1232 unsigned int cmd, unsigned long arg) 1233{ 1234 struct amba_info *info = tty->driver_data; 1235 struct amba_icount cprev, cnow; 1236 struct serial_icounter_struct icount; 1237 unsigned long flags; 1238 1239 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && 1240 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && 1241 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { 1242 if (tty->flags & (1 << TTY_IO_ERROR)) 1243 return -EIO; 1244 } 1245 1246 switch (cmd) { 1247 case TIOCMGET: 1248 return get_modem_info(info, (unsigned int *)arg); 1249 case TIOCMBIS: 1250 case TIOCMBIC: 1251 case TIOCMSET: 1252 return set_modem_info(info, cmd, (unsigned int *)arg); 1253 case TIOCGSERIAL: 1254 return get_serial_info(info, 1255 (struct serial_struct *)arg); 1256 case TIOCSSERIAL: 1257 return set_serial_info(info, 1258 (struct serial_struct *)arg); 1259 case TIOCSERGETLSR: /* Get line status register */ 1260 return get_lsr_info(info, (unsigned int *)arg); 1261 /* 1262 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 1263 * - mask passed in arg for lines of interest 1264 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) 1265 * Caller should use TIOCGICOUNT to see which one it was 1266 */ 1267 case TIOCMIWAIT: 1268 save_flags(flags); cli(); 1269 /* note the counters on entry */ 1270 cprev = info->state->icount; 1271 /* Force modem status interrupts on */ 1272 UART_PUT_CR(info->port, UART_GET_CR(info->port) | AMBA_UARTCR_MSIE); 1273 restore_flags(flags); 1274 while (1) { 1275 interruptible_sleep_on(&info->delta_msr_wait); 1276 /* see if a signal did it */ 1277 if (signal_pending(current)) 1278 return -ERESTARTSYS; 1279 save_flags(flags); cli(); 1280 cnow = info->state->icount; /* atomic copy */ 1281 restore_flags(flags); 1282 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 1283 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) 1284 return -EIO; /* no change => error */ 1285 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 1286 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 1287 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || 1288 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { 1289 return 0; 1290 } 1291 cprev = cnow; 1292 } 1293 /* NOTREACHED */ 1294 1295 /* 1296 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 1297 * Return: write counters to the user passed counter struct 1298 * NB: both 1->0 and 0->1 transitions are counted except for 1299 * RI where only 0->1 is counted. 1300 */ 1301 case TIOCGICOUNT: 1302 save_flags(flags); cli(); 1303 cnow = info->state->icount; 1304 restore_flags(flags); 1305 icount.cts = cnow.cts; 1306 icount.dsr = cnow.dsr; 1307 icount.rng = cnow.rng; 1308 icount.dcd = cnow.dcd; 1309 icount.rx = cnow.rx; 1310 icount.tx = cnow.tx; 1311 icount.frame = cnow.frame; 1312 icount.overrun = cnow.overrun; 1313 icount.parity = cnow.parity; 1314 icount.brk = cnow.brk; 1315 icount.buf_overrun = cnow.buf_overrun; 1316 1317 return copy_to_user((void *)arg, &icount, sizeof(icount)) 1318 ? -EFAULT : 0; 1319 1320 default: 1321 return -ENOIOCTLCMD; 1322 } 1323 return 0; 1324} 1325 1326static void ambauart_set_termios(struct tty_struct *tty, struct termios *old_termios) 1327{ 1328 struct amba_info *info = tty->driver_data; 1329 unsigned long flags; 1330 unsigned int cflag = tty->termios->c_cflag; 1331 1332 if ((cflag ^ old_termios->c_cflag) == 0 && 1333 RELEVENT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) 1334 return; 1335 1336 ambauart_change_speed(info, old_termios); 1337 1338 /* Handle transition to B0 status */ 1339 if ((old_termios->c_cflag & CBAUD) && 1340 !(cflag & CBAUD)) { 1341 save_flags(flags); cli(); 1342 info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR); 1343 info->port->set_mctrl(info->port, info->mctrl); 1344 restore_flags(flags); 1345 } 1346 1347 /* Handle transition away from B0 status */ 1348 if (!(old_termios->c_cflag & CBAUD) && 1349 (cflag & CBAUD)) { 1350 save_flags(flags); cli(); 1351 info->mctrl |= TIOCM_DTR; 1352 if (!(cflag & CRTSCTS) || 1353 !test_bit(TTY_THROTTLED, &tty->flags)) 1354 info->mctrl |= TIOCM_RTS; 1355 info->port->set_mctrl(info->port, info->mctrl); 1356 restore_flags(flags); 1357 } 1358 1359 /* Handle turning off CRTSCTS */ 1360 if ((old_termios->c_cflag & CRTSCTS) && 1361 !(cflag & CRTSCTS)) { 1362 tty->hw_stopped = 0; 1363 ambauart_start(tty); 1364 } 1365 1366} 1367 1368static void ambauart_close(struct tty_struct *tty, struct file *filp) 1369{ 1370 struct amba_info *info = tty->driver_data; 1371 struct amba_state *state; 1372 unsigned long flags; 1373 1374 if (!info) 1375 return; 1376 1377 state = info->state; 1378 1379#if DEBUG 1380 printk("ambauart_close() called\n"); 1381#endif 1382 1383 save_flags(flags); cli(); 1384 1385 if (tty_hung_up_p(filp)) { 1386 MOD_DEC_USE_COUNT; 1387 restore_flags(flags); 1388 return; 1389 } 1390 1391 if ((tty->count == 1) && (state->count != 1)) { 1392 /* 1393 * Uh, oh. tty->count is 1, which means that the tty 1394 * structure will be freed. state->count should always 1395 * be one in these conditions. If it's greater than 1396 * one, we've got real problems, since it means the 1397 * serial port won't be shutdown. 1398 */ 1399 printk("ambauart_close: bad serial port count; tty->count is 1, " 1400 "state->count is %d\n", state->count); 1401 state->count = 1; 1402 } 1403 if (--state->count < 0) { 1404 printk("rs_close: bad serial port count for %s%d: %d\n", 1405 tty->driver.name, info->state->line, state->count); 1406 state->count = 0; 1407 } 1408 if (state->count) { 1409 MOD_DEC_USE_COUNT; 1410 restore_flags(flags); 1411 return; 1412 } 1413 info->flags |= ASYNC_CLOSING; 1414 restore_flags(flags); 1415 /* 1416 * Save the termios structure, since this port may have 1417 * separate termios for callout and dialin. 1418 */ 1419 if (info->flags & ASYNC_NORMAL_ACTIVE) 1420 info->state->normal_termios = *tty->termios; 1421 if (info->flags & ASYNC_CALLOUT_ACTIVE) 1422 info->state->callout_termios = *tty->termios; 1423 /* 1424 * Now we wait for the transmit buffer to clear; and we notify 1425 * the line discipline to only process XON/XOFF characters. 1426 */ 1427 tty->closing = 1; 1428 if (info->state->closing_wait != ASYNC_CLOSING_WAIT_NONE) 1429 tty_wait_until_sent(tty, info->state->closing_wait); 1430 /* 1431 * At this point, we stop accepting input. To do this, we 1432 * disable the receive line status interrupts. 1433 */ 1434 if (info->flags & ASYNC_INITIALIZED) { 1435 ambauart_disable_rx_interrupt(info); 1436 /* 1437 * Before we drop DTR, make sure the UART transmitter 1438 * has completely drained; this is especially 1439 * important if there is a transmit FIFO! 1440 */ 1441 ambauart_wait_until_sent(tty, info->timeout); 1442 } 1443 ambauart_shutdown(info); 1444 if (tty->driver.flush_buffer) 1445 tty->driver.flush_buffer(tty); 1446 if (tty->ldisc.flush_buffer) 1447 tty->ldisc.flush_buffer(tty); 1448 tty->closing = 0; 1449 info->event = 0; 1450 info->tty = NULL; 1451 if (info->blocked_open) { 1452 if (info->state->close_delay) { 1453 set_current_state(TASK_INTERRUPTIBLE); 1454 schedule_timeout(info->state->close_delay); 1455 } 1456 wake_up_interruptible(&info->open_wait); 1457 } 1458 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE| 1459 ASYNC_CLOSING); 1460 wake_up_interruptible(&info->close_wait); 1461 MOD_DEC_USE_COUNT; 1462} 1463 1464static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout) 1465{ 1466 struct amba_info *info = (struct amba_info *) tty->driver_data; 1467 unsigned long char_time, expire; 1468 unsigned int status; 1469 1470 if (info->port->fifosize == 0) 1471 return; 1472 1473 /* 1474 * Set the check interval to be 1/5 of the estimated time to 1475 * send a single character, and make it at least 1. The check 1476 * interval should also be less than the timeout. 1477 * 1478 * Note: we have to use pretty tight timings here to satisfy 1479 * the NIST-PCTS. 1480 */ 1481 char_time = (info->timeout - HZ/50) / info->port->fifosize; 1482 char_time = char_time / 5; 1483 if (char_time == 0) 1484 char_time = 1; 1485 if (timeout && timeout < char_time) 1486 char_time = timeout; 1487 /* 1488 * If the transmitter hasn't cleared in twice the approximate 1489 * amount of time to send the entire FIFO, it probably won't 1490 * ever clear. This assumes the UART isn't doing flow 1491 * control, which is currently the case. Hence, if it ever 1492 * takes longer than info->timeout, this is probably due to a 1493 * UART bug of some kind. So, we clamp the timeout parameter at 1494 * 2*info->timeout. 1495 */ 1496 if (!timeout || timeout > 2 * info->timeout) 1497 timeout = 2 * info->timeout; 1498 1499 expire = jiffies + timeout; 1500#if DEBUG 1501 printk("ambauart_wait_until_sent(%d), jiff=%lu, expire=%lu...\n", 1502 MINOR(tty->device) - tty->driver.minor_start, jiffies, 1503 expire); 1504#endif 1505 while (UART_GET_FR(info->port) & AMBA_UARTFR_BUSY) { 1506 set_current_state(TASK_INTERRUPTIBLE); 1507 schedule_timeout(char_time); 1508 if (signal_pending(current)) 1509 break; 1510 if (timeout && time_after(jiffies, expire)) 1511 break; 1512 status = UART_GET_FR(info->port); 1513 } 1514 set_current_state(TASK_RUNNING); 1515} 1516 1517static void ambauart_hangup(struct tty_struct *tty) 1518{ 1519 struct amba_info *info = tty->driver_data; 1520 struct amba_state *state = info->state; 1521 1522 ambauart_flush_buffer(tty); 1523 if (info->flags & ASYNC_CLOSING) 1524 return; 1525 ambauart_shutdown(info); 1526 info->event = 0; 1527 state->count = 0; 1528 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); 1529 info->tty = NULL; 1530 wake_up_interruptible(&info->open_wait); 1531} 1532 1533static int block_til_ready(struct tty_struct *tty, struct file *filp, 1534 struct amba_info *info) 1535{ 1536 DECLARE_WAITQUEUE(wait, current); 1537 struct amba_state *state = info->state; 1538 unsigned long flags; 1539 int do_clocal = 0, extra_count = 0, retval; 1540 1541 /* 1542 * If the device is in the middle of being closed, then block 1543 * until it's done, and then try again. 1544 */ 1545 if (tty_hung_up_p(filp) || 1546 (info->flags & ASYNC_CLOSING)) { 1547 if (info->flags & ASYNC_CLOSING) 1548 interruptible_sleep_on(&info->close_wait); 1549 return (info->flags & ASYNC_HUP_NOTIFY) ? 1550 -EAGAIN : -ERESTARTSYS; 1551 } 1552 1553 /* 1554 * If this is a callout device, then just make sure the normal 1555 * device isn't being used. 1556 */ 1557 if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) { 1558 if (info->flags & ASYNC_NORMAL_ACTIVE) 1559 return -EBUSY; 1560 if ((info->flags & ASYNC_CALLOUT_ACTIVE) && 1561 (info->flags & ASYNC_SESSION_LOCKOUT) && 1562 (info->session != current->session)) 1563 return -EBUSY; 1564 if ((info->flags & ASYNC_CALLOUT_ACTIVE) && 1565 (info->flags & ASYNC_PGRP_LOCKOUT) && 1566 (info->pgrp != current->pgrp)) 1567 return -EBUSY; 1568 info->flags |= ASYNC_CALLOUT_ACTIVE; 1569 return 0; 1570 } 1571 1572 /* 1573 * If non-blocking mode is set, or the port is not enabled, 1574 * then make the check up front and then exit. 1575 */ 1576 if ((filp->f_flags & O_NONBLOCK) || 1577 (tty->flags & (1 << TTY_IO_ERROR))) { 1578 if (info->flags & ASYNC_CALLOUT_ACTIVE) 1579 return -EBUSY; 1580 info->flags |= ASYNC_NORMAL_ACTIVE; 1581 return 0; 1582 } 1583 1584 if (info->flags & ASYNC_CALLOUT_ACTIVE) { 1585 if (state->normal_termios.c_cflag & CLOCAL) 1586 do_clocal = 1; 1587 } else { 1588 if (tty->termios->c_cflag & CLOCAL) 1589 do_clocal = 1; 1590 } 1591 1592 /* 1593 * Block waiting for the carrier detect and the line to become 1594 * free (i.e., not in use by the callout). While we are in 1595 * this loop, state->count is dropped by one, so that 1596 * rs_close() knows when to free things. We restore it upon 1597 * exit, either normal or abnormal. 1598 */ 1599 retval = 0; 1600 add_wait_queue(&info->open_wait, &wait); 1601 save_flags(flags); cli(); 1602 if (!tty_hung_up_p(filp)) { 1603 extra_count = 1; 1604 state->count--; 1605 } 1606 restore_flags(flags); 1607 info->blocked_open++; 1608 while (1) { 1609 save_flags(flags); cli(); 1610 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && 1611 (tty->termios->c_cflag & CBAUD)) { 1612 info->mctrl = TIOCM_DTR | TIOCM_RTS; 1613 info->port->set_mctrl(info->port, info->mctrl); 1614 } 1615 restore_flags(flags); 1616 set_current_state(TASK_INTERRUPTIBLE); 1617 if (tty_hung_up_p(filp) || 1618 !(info->flags & ASYNC_INITIALIZED)) { 1619 if (info->flags & ASYNC_HUP_NOTIFY) 1620 retval = -EAGAIN; 1621 else 1622 retval = -ERESTARTSYS; 1623 break; 1624 } 1625 if (!(info->flags & ASYNC_CALLOUT_ACTIVE) && 1626 !(info->flags & ASYNC_CLOSING) && 1627 (do_clocal || (UART_GET_FR(info->port) & AMBA_UARTFR_DCD))) 1628 break; 1629 if (signal_pending(current)) { 1630 retval = -ERESTARTSYS; 1631 break; 1632 } 1633 schedule(); 1634 } 1635 set_current_state(TASK_RUNNING); 1636 remove_wait_queue(&info->open_wait, &wait); 1637 if (extra_count) 1638 state->count++; 1639 info->blocked_open--; 1640 if (retval) 1641 return retval; 1642 info->flags |= ASYNC_NORMAL_ACTIVE; 1643 return 0; 1644} 1645 1646static struct amba_info *ambauart_get(int line) 1647{ 1648 struct amba_info *info; 1649 struct amba_state *state = amba_state + line; 1650 1651 state->count++; 1652 if (state->info) 1653 return state->info; 1654 info = kmalloc(sizeof(struct amba_info), GFP_KERNEL); 1655 if (info) { 1656 memset(info, 0, sizeof(struct amba_info)); 1657 init_waitqueue_head(&info->open_wait); 1658 init_waitqueue_head(&info->close_wait); 1659 init_waitqueue_head(&info->delta_msr_wait); 1660 info->flags = state->flags; 1661 info->state = state; 1662 info->port = amba_ports + line; 1663 tasklet_init(&info->tlet, ambauart_tasklet_action, 1664 (unsigned long)info); 1665 } 1666 if (state->info) { 1667 kfree(info); 1668 return state->info; 1669 } 1670 state->info = info; 1671 return info; 1672} 1673 1674static int ambauart_open(struct tty_struct *tty, struct file *filp) 1675{ 1676 struct amba_info *info; 1677 int retval, line = MINOR(tty->device) - tty->driver.minor_start; 1678 1679#if DEBUG 1680 printk("ambauart_open(%d) called\n", line); 1681#endif 1682 1683 // is this a line that we've got? 1684 MOD_INC_USE_COUNT; 1685 if (line >= SERIAL_AMBA_NR) { 1686 MOD_DEC_USE_COUNT; 1687 return -ENODEV; 1688 } 1689 1690 info = ambauart_get(line); 1691 if (!info) 1692 return -ENOMEM; 1693 1694 tty->driver_data = info; 1695 info->tty = tty; 1696 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1697 1698 /* 1699 * Make sure we have the temporary buffer allocated 1700 */ 1701 if (!tmp_buf) { 1702 unsigned long page = get_zeroed_page(GFP_KERNEL); 1703 if (tmp_buf) 1704 free_page(page); 1705 else if (!page) { 1706 MOD_DEC_USE_COUNT; 1707 return -ENOMEM; 1708 } 1709 tmp_buf = (u_char *)page; 1710 } 1711 1712 /* 1713 * If the port is in the middle of closing, bail out now. 1714 */ 1715 if (tty_hung_up_p(filp) || 1716 (info->flags & ASYNC_CLOSING)) { 1717 if (info->flags & ASYNC_CLOSING) 1718 interruptible_sleep_on(&info->close_wait); 1719 MOD_DEC_USE_COUNT; 1720 return -EAGAIN; 1721 } 1722 1723 /* 1724 * Start up the serial port 1725 */ 1726 retval = ambauart_startup(info); 1727 if (retval) { 1728 MOD_DEC_USE_COUNT; 1729 return retval; 1730 } 1731 1732 retval = block_til_ready(tty, filp, info); 1733 if (retval) { 1734 MOD_DEC_USE_COUNT; 1735 return retval; 1736 } 1737 1738 if ((info->state->count == 1) && 1739 (info->flags & ASYNC_SPLIT_TERMIOS)) { 1740 if (tty->driver.subtype == SERIAL_TYPE_NORMAL) 1741 *tty->termios = info->state->normal_termios; 1742 else 1743 *tty->termios = info->state->callout_termios; 1744 } 1745#ifdef CONFIG_SERIAL_AMBA_CONSOLE 1746 if (ambauart_cons.cflag && ambauart_cons.index == line) { 1747 tty->termios->c_cflag = ambauart_cons.cflag; 1748 ambauart_cons.cflag = 0; 1749 } 1750#endif 1751 ambauart_change_speed(info, NULL); 1752 info->session = current->session; 1753 info->pgrp = current->pgrp; 1754 return 0; 1755} 1756 1757int __init ambauart_init(void) 1758{ 1759 int i; 1760 1761 ambanormal_driver.magic = TTY_DRIVER_MAGIC; 1762 ambanormal_driver.driver_name = "serial_amba"; 1763 ambanormal_driver.name = SERIAL_AMBA_NAME; 1764 ambanormal_driver.major = SERIAL_AMBA_MAJOR; 1765 ambanormal_driver.minor_start = SERIAL_AMBA_MINOR; 1766 ambanormal_driver.num = SERIAL_AMBA_NR; 1767 ambanormal_driver.type = TTY_DRIVER_TYPE_SERIAL; 1768 ambanormal_driver.subtype = SERIAL_TYPE_NORMAL; 1769 ambanormal_driver.init_termios = tty_std_termios; 1770 ambanormal_driver.init_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; 1771 ambanormal_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; 1772 ambanormal_driver.refcount = &ambauart_refcount; 1773 ambanormal_driver.table = ambauart_table; 1774 ambanormal_driver.termios = ambauart_termios; 1775 ambanormal_driver.termios_locked = ambauart_termios_locked; 1776 1777 ambanormal_driver.open = ambauart_open; 1778 ambanormal_driver.close = ambauart_close; 1779 ambanormal_driver.write = ambauart_write; 1780 ambanormal_driver.put_char = ambauart_put_char; 1781 ambanormal_driver.flush_chars = ambauart_flush_chars; 1782 ambanormal_driver.write_room = ambauart_write_room; 1783 ambanormal_driver.chars_in_buffer = ambauart_chars_in_buffer; 1784 ambanormal_driver.flush_buffer = ambauart_flush_buffer; 1785 ambanormal_driver.ioctl = ambauart_ioctl; 1786 ambanormal_driver.throttle = ambauart_throttle; 1787 ambanormal_driver.unthrottle = ambauart_unthrottle; 1788 ambanormal_driver.send_xchar = ambauart_send_xchar; 1789 ambanormal_driver.set_termios = ambauart_set_termios; 1790 ambanormal_driver.stop = ambauart_stop; 1791 ambanormal_driver.start = ambauart_start; 1792 ambanormal_driver.hangup = ambauart_hangup; 1793 ambanormal_driver.break_ctl = ambauart_break_ctl; 1794 ambanormal_driver.wait_until_sent = ambauart_wait_until_sent; 1795 ambanormal_driver.read_proc = NULL; 1796 1797 /* 1798 * The callout device is just like the normal device except for 1799 * the major number and the subtype code. 1800 */ 1801 ambacallout_driver = ambanormal_driver; 1802 ambacallout_driver.name = CALLOUT_AMBA_NAME; 1803 ambacallout_driver.major = CALLOUT_AMBA_MAJOR; 1804 ambacallout_driver.subtype = SERIAL_TYPE_CALLOUT; 1805 ambacallout_driver.read_proc = NULL; 1806 ambacallout_driver.proc_entry = NULL; 1807 1808 if (tty_register_driver(&ambanormal_driver)) 1809 panic("Couldn't register AMBA serial driver\n"); 1810 if (tty_register_driver(&ambacallout_driver)) 1811 panic("Couldn't register AMBA callout driver\n"); 1812 1813 for (i = 0; i < SERIAL_AMBA_NR; i++) { 1814 struct amba_state *state = amba_state + i; 1815 state->line = i; 1816 state->close_delay = 5 * HZ / 10; 1817 state->closing_wait = 30 * HZ; 1818 state->callout_termios = ambacallout_driver.init_termios; 1819 state->normal_termios = ambanormal_driver.init_termios; 1820 } 1821 1822 return 0; 1823} 1824 1825__initcall(ambauart_init); 1826 1827#ifdef CONFIG_SERIAL_AMBA_CONSOLE 1828/************** console driver *****************/ 1829 1830#ifdef used_and_not_const_char_pointer 1831static int ambauart_console_read(struct console *co, const char *s, u_int count) 1832{ 1833 struct amba_port *port = &amba_ports[co->index]; 1834 unsigned int status; 1835 char *w; 1836 int c; 1837#if DEBUG 1838 printk("ambauart_console_read() called\n"); 1839#endif 1840 1841 c = 0; 1842 w = s; 1843 while (c < count) { 1844 status = UART_GET_FR(port); 1845 if (UART_RX_DATA(status)) { 1846 *w++ = UART_GET_CHAR(port); 1847 c++; 1848 } else { 1849 // nothing more to get, return 1850 return c; 1851 } 1852 } 1853 // return the count 1854 return c; 1855} 1856#endif 1857 1858/* 1859 * Print a string to the serial port trying not to disturb 1860 * any possible real use of the port... 1861 * 1862 * The console must be locked when we get here. 1863 */ 1864static void ambauart_console_write(struct console *co, const char *s, u_int count) 1865{ 1866 struct amba_port *port = &amba_ports[co->index]; 1867 unsigned int status, old_cr; 1868 int i; 1869 1870 /* 1871 * First save the CR then disable the interrupts 1872 */ 1873 old_cr = UART_GET_CR(port); 1874 UART_PUT_CR(port, AMBA_UARTCR_UARTEN); 1875 1876 /* 1877 * Now, do each character 1878 */ 1879 for (i = 0; i < count; i++) { 1880 do { 1881 status = UART_GET_FR(port); 1882 } while (!UART_TX_READY(status)); 1883 UART_PUT_CHAR(port, s[i]); 1884 if (s[i] == '\n') { 1885 do { 1886 status = UART_GET_FR(port); 1887 } while (!UART_TX_READY(status)); 1888 UART_PUT_CHAR(port, '\r'); 1889 } 1890 } 1891 1892 /* 1893 * Finally, wait for transmitter to become empty 1894 * and restore the TCR 1895 */ 1896 do { 1897 status = UART_GET_FR(port); 1898 } while (status & AMBA_UARTFR_BUSY); 1899 UART_PUT_CR(port, old_cr); 1900} 1901 1902static kdev_t ambauart_console_device(struct console *c) 1903{ 1904 return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + c->index); 1905} 1906 1907static int __init ambauart_console_setup(struct console *co, char *options) 1908{ 1909 struct amba_port *port; 1910 int baud = 38400; 1911 int bits = 8; 1912 int parity = 'n'; 1913 u_int cflag = CREAD | HUPCL | CLOCAL; 1914 u_int lcr_h, quot; 1915 1916 if (co->index >= SERIAL_AMBA_NR) 1917 co->index = 0; 1918 1919 port = &amba_ports[co->index]; 1920 1921 if (options) { 1922 char *s = options; 1923 baud = simple_strtoul(s, NULL, 10); 1924 while (*s >= '0' && *s <= '9') 1925 s++; 1926 if (*s) parity = *s++; 1927 if (*s) bits = *s - '0'; 1928 } 1929 1930 /* 1931 * Now construct a cflag setting. 1932 */ 1933 switch (baud) { 1934 case 1200: cflag |= B1200; break; 1935 case 2400: cflag |= B2400; break; 1936 case 4800: cflag |= B4800; break; 1937 default: cflag |= B9600; baud = 9600; break; 1938 case 19200: cflag |= B19200; break; 1939 case 38400: cflag |= B38400; break; 1940 case 57600: cflag |= B57600; break; 1941 case 115200: cflag |= B115200; break; 1942 } 1943 switch (bits) { 1944 case 7: cflag |= CS7; lcr_h = AMBA_UARTLCR_H_WLEN_7; break; 1945 default: cflag |= CS8; lcr_h = AMBA_UARTLCR_H_WLEN_8; break; 1946 } 1947 switch (parity) { 1948 case 'o': 1949 case 'O': cflag |= PARODD; lcr_h |= AMBA_UARTLCR_H_PEN; break; 1950 case 'e': 1951 case 'E': cflag |= PARENB; lcr_h |= AMBA_UARTLCR_H_PEN | 1952 AMBA_UARTLCR_H_EPS; break; 1953 } 1954 1955 co->cflag = cflag; 1956 1957 if (port->fifosize > 1) 1958 lcr_h |= AMBA_UARTLCR_H_FEN; 1959 1960 quot = (port->uartclk / (16 * baud)) - 1; 1961 1962 UART_PUT_LCRL(port, (quot & 0xff)); 1963 UART_PUT_LCRM(port, (quot >> 8)); 1964 UART_PUT_LCRH(port, lcr_h); 1965 1966 /* we will enable the port as we need it */ 1967 UART_PUT_CR(port, 0); 1968 1969 return 0; 1970} 1971 1972static struct console ambauart_cons = 1973{ 1974 name: SERIAL_AMBA_NAME, 1975 write: ambauart_console_write, 1976#ifdef used_and_not_const_char_pointer 1977 read: ambauart_console_read, 1978#endif 1979 device: ambauart_console_device, 1980 setup: ambauart_console_setup, 1981 flags: CON_PRINTBUFFER, 1982 index: -1, 1983}; 1984 1985void __init ambauart_console_init(void) 1986{ 1987 register_console(&ambauart_cons); 1988} 1989 1990#endif /* CONFIG_SERIAL_AMBA_CONSOLE */ 1991 1992MODULE_LICENSE("GPL"); 1993EXPORT_NO_SYMBOLS; 1994