1/* 2 * Driver for IBM STB3xxx SICC serial port 3 * 4 * Based on drivers/char/serial_amba.c, by ARM Ltd. 5 * 6 * Copyright 2001 IBM Corp. 7 * Author: IBM China Research Lab 8 * Yudong Yang <yangyud@cn.ibm.com> 9 * Yi Ge <geyi@cn.ibm.com> 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 driver for SICC serial port on IBM Redwood 4 evaluation board. 27 * The driver support both as a console device and normal serial device and 28 * is compatible with normal ttyS* devices. 29 */ 30 31#include <linux/module.h> 32#include <linux/kernel.h> 33#include <linux/errno.h> 34#include <linux/signal.h> 35#include <linux/sched.h> 36#include <linux/interrupt.h> 37#include <linux/tty.h> 38#include <linux/tty_flip.h> 39#include <linux/major.h> 40#include <linux/string.h> 41#include <linux/fcntl.h> 42#include <linux/ptrace.h> 43#include <linux/ioport.h> 44#include <linux/mm.h> 45#include <linux/slab.h> 46#include <linux/init.h> 47#include <linux/capability.h> 48#include <linux/circ_buf.h> 49#include <linux/serial.h> 50#include <linux/console.h> 51#include <linux/sysrq.h> 52#include <linux/bitops.h> 53 54#include <asm/system.h> 55#include <asm/io.h> 56#include <asm/irq.h> 57#include <asm/uaccess.h> 58#include <asm/serial.h> 59 60 61#include <linux/serialP.h> 62 63 64/* ----------------------------------------------------------------------------- 65 * From STB03xxx SICC UART Specification 66 * ----------------------------------------------------------------------------- 67 * UART Register Offsets. 68 */ 69 70#define BL_SICC_LSR 0x0000000 /* line status register read/clear */ 71#define BL_SICC_LSRS 0x0000001 /* set line status register read/set */ 72#define BL_SICC_HSR 0x0000002 /* handshake status register r/clear */ 73#define BL_SICC_HSRS 0x0000003 /* set handshake status register r/set */ 74#define BL_SICC_BRDH 0x0000004 /* baudrate divisor high reg r/w */ 75#define BL_SICC_BRDL 0x0000005 /* baudrate divisor low reg r/w */ 76#define BL_SICC_LCR 0x0000006 /* control register r/w */ 77#define BL_SICC_RCR 0x0000007 /* receiver command register r/w */ 78#define BL_SICC_TxCR 0x0000008 /* transmitter command register r/w */ 79#define BL_SICC_RBR 0x0000009 /* receive buffer r */ 80#define BL_SICC_TBR 0x0000009 /* transmit buffer w */ 81#define BL_SICC_CTL2 0x000000A /* added for Vesta */ 82#define BL_SICC_IrCR 0x000000B /* added for Vesta IR */ 83 84/* masks and definitions for serial port control register */ 85 86#define _LCR_LM_MASK 0xc0 /* loop back modes */ 87#define _LCR_DTR_MASK 0x20 /* data terminal ready 0-inactive */ 88#define _LCR_RTS_MASK 0x10 /* request to send 0-inactive */ 89#define _LCR_DB_MASK 0x08 /* data bits mask */ 90#define _LCR_PE_MASK 0x04 /* parity enable */ 91#define _LCR_PTY_MASK 0x02 /* parity */ 92#define _LCR_SB_MASK 0x01 /* stop bit mask */ 93 94#define _LCR_LM_NORM 0x00 /* normal operation */ 95#define _LCR_LM_LOOP 0x40 /* internal loopback mode */ 96#define _LCR_LM_ECHO 0x80 /* automatic echo mode */ 97#define _LCR_LM_RES 0xc0 /* reserved */ 98 99#define _LCR_DTR_ACTIVE _LCR_DTR_MASK /* DTR is active */ 100#define _LCR_RTS_ACTIVE _LCR_RTS_MASK /* RTS is active */ 101#define _LCR_DB_8_BITS _LCR_DB_MASK /* 8 data bits */ 102#define _LCR_DB_7_BITS 0x00 /* 7 data bits */ 103#define _LCR_PE_ENABLE _LCR_PE_MASK /* parity enabled */ 104#define _LCR_PE_DISABLE 0x00 /* parity disabled */ 105#define _LCR_PTY_EVEN 0x00 /* even parity */ 106#define _LCR_PTY_ODD _LCR_PTY_MASK /* odd parity */ 107#define _LCR_SB_1_BIT 0x00 /* one stop bit */ 108#define _LCR_SB_2_BIT _LCR_SB_MASK /* two stop bit */ 109 110/* serial port handshake register */ 111 112#define _HSR_DIS_MASK 0x80 /* DSR input inactive error mask */ 113#define _HSR_CS_MASK 0x40 /* CTS input inactive error mask */ 114#define _HSR_DIS_ACT 0x00 /* dsr input is active */ 115#define _HSR_DIS_INACT _HSR_DIS_MASK /* dsr input is inactive */ 116#define _HSR_CS_ACT 0x00 /* cts input is active */ 117#define _HSR_CS_INACT _HSR_CS_MASK /* cts input is active */ 118 119/* serial port line status register */ 120 121#define _LSR_RBR_MASK 0x80 /* receive buffer ready mask */ 122#define _LSR_FE_MASK 0x40 /* framing error */ 123#define _LSR_OE_MASK 0x20 /* overrun error */ 124#define _LSR_PE_MASK 0x10 /* parity error */ 125#define _LSR_LB_MASK 0x08 /* line break */ 126#define _LSR_TBR_MASK 0x04 /* transmit buffer ready */ 127#define _LSR_TSR_MASK 0x02 /* transmit shift register ready */ 128 129#define _LSR_RBR_FULL _LSR_RBR_MASK /* receive buffer is full */ 130#define _LSR_FE_ERROR _LSR_FE_MASK /* framing error detected */ 131#define _LSR_OE_ERROR _LSR_OE_MASK /* overrun error detected */ 132#define _LSR_PE_ERROR _LSR_PE_MASK /* parity error detected */ 133#define _LSR_LB_BREAK _LSR_LB_MASK /* line break detected */ 134#define _LSR_TBR_EMPTY _LSR_TBR_MASK /* transmit buffer is ready */ 135#define _LSR_TSR_EMPTY _LSR_TSR_MASK /* transmit shift register is empty */ 136#define _LSR_TX_ALL 0x06 /* all physical transmit is done */ 137 138#define _LSR_RX_ERR (_LSR_LB_BREAK | _LSR_FE_MASK | _LSR_OE_MASK | \ 139 _LSR_PE_MASK ) 140 141/* serial port receiver command register */ 142 143#define _RCR_ER_MASK 0x80 /* enable receiver mask */ 144#define _RCR_DME_MASK 0x60 /* dma mode */ 145#define _RCR_EIE_MASK 0x10 /* error interrupt enable mask */ 146#define _RCR_PME_MASK 0x08 /* pause mode mask */ 147 148#define _RCR_ER_ENABLE _RCR_ER_MASK /* receiver enabled */ 149#define _RCR_DME_DISABLE 0x00 /* dma disabled */ 150#define _RCR_DME_RXRDY 0x20 /* dma disabled, RxRDY interrupt enabled*/ 151#define _RCR_DME_ENABLE2 0x40 /* dma enabled,receiver src channel 2 */ 152#define _RCR_DME_ENABLE3 0x60 /* dma enabled,receiver src channel 3 */ 153#define _RCR_PME_HARD _RCR_PME_MASK /* RTS controlled by hardware */ 154#define _RCR_PME_SOFT 0x00 /* RTS controlled by software */ 155 156/* serial port transmit command register */ 157 158#define _TxCR_ET_MASK 0x80 /* transmitter enable mask */ 159#define _TxCR_DME_MASK 0x60 /* dma mode mask */ 160#define _TxCR_TIE_MASK 0x10 /* empty interrupt enable mask */ 161#define _TxCR_EIE_MASK 0x08 /* error interrupt enable mask */ 162#define _TxCR_SPE_MASK 0x04 /* stop/pause mask */ 163#define _TxCR_TB_MASK 0x02 /* transmit break mask */ 164 165#define _TxCR_ET_ENABLE _TxCR_ET_MASK /* transmitter enabled */ 166#define _TxCR_DME_DISABLE 0x00 /* transmitter disabled, TBR intr disabled */ 167#define _TxCR_DME_TBR 0x20 /* transmitter disabled, TBR intr enabled */ 168#define _TxCR_DME_CHAN_2 0x40 /* dma enabled, destination chann 2 */ 169#define _TxCR_DME_CHAN_3 0x60 /* dma enabled, destination chann 3 */ 170 171/* serial ctl reg 2 - added for Vesta */ 172 173#define _CTL2_EXTERN 0x80 /* */ 174#define _CTL2_USEFIFO 0x40 /* */ 175#define _CTL2_RESETRF 0x08 /* */ 176#define _CTL2_RESETTF 0x04 /* */ 177 178 179 180#define SERIAL_SICC_NAME "ttySICC" 181#define SERIAL_SICC_MAJOR 150 182#define SERIAL_SICC_MINOR 1 183#define SERIAL_SICC_NR 1 184 185#ifndef TRUE 186#define TRUE 1 187#endif 188#ifndef FALSE 189#define FALSE 0 190#endif 191 192/* 193 * Things needed by tty driver 194 */ 195static struct tty_driver *siccnormal_driver; 196 197#if defined(CONFIG_SERIAL_SICC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 198#define SUPPORT_SYSRQ 199#endif 200 201/* 202 * Things needed internally to this driver 203 */ 204 205/* 206 * tmp_buf is used as a temporary buffer by serial_write. We need to 207 * lock it in case the copy_from_user blocks while swapping in a page, 208 * and some other program tries to do a serial write at the same time. 209 * Since the lock will only come under contention when the system is 210 * swapping and available memory is low, it makes sense to share one 211 * buffer across all the serial ports, since it significantly saves 212 * memory if large numbers of serial ports are open. 213 */ 214static u_char *tmp_buf; 215 216#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 217 218/* number of characters left in xmit buffer before we ask for more */ 219#define WAKEUP_CHARS 256 220#define SICC_ISR_PASS_LIMIT 256 221 222#define EVT_WRITE_WAKEUP 0 223 224struct SICC_icount { 225 __u32 cts; 226 __u32 dsr; 227 __u32 rng; 228 __u32 dcd; 229 __u32 rx; 230 __u32 tx; 231 __u32 frame; 232 __u32 overrun; 233 __u32 parity; 234 __u32 brk; 235 __u32 buf_overrun; 236}; 237 238/* 239 * Static information about the port 240 */ 241struct SICC_port { 242 unsigned int uart_base; 243 unsigned int uart_base_phys; 244 unsigned int irqrx; 245 unsigned int irqtx; 246 unsigned int uartclk; 247 unsigned int fifosize; 248 unsigned int tiocm_support; 249 void (*set_mctrl)(struct SICC_port *, u_int mctrl); 250}; 251 252/* 253 * This is the state information which is persistent across opens 254 */ 255struct SICC_state { 256 struct SICC_icount icount; 257 unsigned int line; 258 unsigned int close_delay; 259 unsigned int closing_wait; 260 unsigned int custom_divisor; 261 unsigned int flags; 262 int count; 263 struct SICC_info *info; 264 spinlock_t sicc_lock; 265}; 266 267#define SICC_XMIT_SIZE 1024 268/* 269 * This is the state information which is only valid when the port is open. 270 */ 271struct SICC_info { 272 struct SICC_port *port; 273 struct SICC_state *state; 274 struct tty_struct *tty; 275 unsigned char x_char; 276 unsigned char old_status; 277 unsigned char read_status_mask; 278 unsigned char ignore_status_mask; 279 struct circ_buf xmit; 280 unsigned int flags; 281#ifdef SUPPORT_SYSRQ 282 unsigned long sysrq; 283#endif 284 285 unsigned int event; 286 unsigned int timeout; 287 unsigned int lcr_h; 288 unsigned int mctrl; 289 int blocked_open; 290 291 struct tasklet_struct tlet; 292 293 wait_queue_head_t open_wait; 294 wait_queue_head_t close_wait; 295 wait_queue_head_t delta_msr_wait; 296}; 297 298#ifdef CONFIG_SERIAL_SICC_CONSOLE 299static struct console siccuart_cons; 300#endif 301static void siccuart_change_speed(struct SICC_info *info, struct termios *old_termios); 302static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout); 303 304 305 306static void powerpcMtcic_cr(unsigned long value) 307{ 308 mtdcr(DCRN_CICCR, value); 309} 310 311static unsigned long powerpcMfcic_cr(void) 312{ 313 return mfdcr(DCRN_CICCR); 314} 315 316static unsigned long powerpcMfclkgpcr(void) 317{ 318 return mfdcr(DCRN_SCCR); 319} 320 321static void sicc_set_mctrl_null(struct SICC_port *port, u_int mctrl) 322{ 323} 324 325static struct SICC_port sicc_ports[SERIAL_SICC_NR] = { 326 { 327 .uart_base = 0, 328 .uart_base_phys = SICC0_IO_BASE, 329 .irqrx = SICC0_INTRX, 330 .irqtx = SICC0_INTTX, 331// .uartclk = 0, 332 .fifosize = 1, 333 .set_mctrl = sicc_set_mctrl_null, 334 } 335}; 336 337static struct SICC_state sicc_state[SERIAL_SICC_NR]; 338 339static void siccuart_enable_rx_interrupt(struct SICC_info *info) 340{ 341 unsigned char cr; 342 343 cr = readb(info->port->uart_base+BL_SICC_RCR); 344 cr &= ~_RCR_DME_MASK; 345 cr |= _RCR_DME_RXRDY; 346 writeb(cr, info->port->uart_base+BL_SICC_RCR); 347} 348 349static void siccuart_disable_rx_interrupt(struct SICC_info *info) 350{ 351 unsigned char cr; 352 353 cr = readb(info->port->uart_base+BL_SICC_RCR); 354 cr &= ~_RCR_DME_MASK; 355 cr |= _RCR_DME_DISABLE; 356 writeb(cr, info->port->uart_base+BL_SICC_RCR); 357} 358 359 360static void siccuart_enable_tx_interrupt(struct SICC_info *info) 361{ 362 unsigned char cr; 363 364 cr = readb(info->port->uart_base+BL_SICC_TxCR); 365 cr &= ~_TxCR_DME_MASK; 366 cr |= _TxCR_DME_TBR; 367 writeb(cr, info->port->uart_base+BL_SICC_TxCR); 368} 369 370static void siccuart_disable_tx_interrupt(struct SICC_info *info) 371{ 372 unsigned char cr; 373 374 cr = readb(info->port->uart_base+BL_SICC_TxCR); 375 cr &= ~_TxCR_DME_MASK; 376 cr |= _TxCR_DME_DISABLE; 377 writeb(cr, info->port->uart_base+BL_SICC_TxCR); 378} 379 380 381static void siccuart_stop(struct tty_struct *tty) 382{ 383 struct SICC_info *info = tty->driver_data; 384 unsigned long flags; 385 386 /* disable interrupts while stopping serial port interrupts */ 387 spin_lock_irqsave(&info->state->sicc_lock,flags); 388 siccuart_disable_tx_interrupt(info); 389 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 390} 391 392static void siccuart_start(struct tty_struct *tty) 393{ 394 struct SICC_info *info = tty->driver_data; 395 unsigned long flags; 396 397 /* disable interrupts while starting serial port interrupts */ 398 spin_lock_irqsave(&info->state->sicc_lock,flags); 399 if (info->xmit.head != info->xmit.tail 400 && info->xmit.buf) 401 siccuart_enable_tx_interrupt(info); 402 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 403} 404 405 406/* 407 * This routine is used by the interrupt handler to schedule 408 * processing in the software interrupt portion of the driver. 409 */ 410static void siccuart_event(struct SICC_info *info, int event) 411{ 412 info->event |= 1 << event; 413 tasklet_schedule(&info->tlet); 414} 415 416static void 417siccuart_rx_chars(struct SICC_info *info) 418{ 419 struct tty_struct *tty = info->tty; 420 unsigned int status, ch, rsr, flg, ignored = 0; 421 struct SICC_icount *icount = &info->state->icount; 422 struct SICC_port *port = info->port; 423 424 status = readb(port->uart_base+BL_SICC_LSR ); 425 while (status & _LSR_RBR_FULL) { 426 ch = readb(port->uart_base+BL_SICC_RBR); 427 428 if (tty->flip.count >= TTY_FLIPBUF_SIZE) 429 goto ignore_char; 430 icount->rx++; 431 432 flg = TTY_NORMAL; 433 434 /* 435 * Note that the error handling code is 436 * out of the main execution path 437 */ 438 rsr = readb(port->uart_base+BL_SICC_LSR); 439 if (rsr & _LSR_RX_ERR) 440 goto handle_error; 441#ifdef SUPPORT_SYSRQ 442 if (info->sysrq) { 443 if (ch && time_before(jiffies, info->sysrq)) { 444 handle_sysrq(ch, NULL); 445 info->sysrq = 0; 446 goto ignore_char; 447 } 448 info->sysrq = 0; 449 } 450#endif 451 error_return: 452 *tty->flip.flag_buf_ptr++ = flg; 453 *tty->flip.char_buf_ptr++ = ch; 454 tty->flip.count++; 455 ignore_char: 456 status = readb(port->uart_base+BL_SICC_LSR ); 457 } 458out: 459 tty_flip_buffer_push(tty); 460 return; 461 462handle_error: 463 if (rsr & _LSR_LB_BREAK) { 464 rsr &= ~(_LSR_FE_MASK | _LSR_PE_MASK); 465 icount->brk++; 466 467#ifdef SUPPORT_SYSRQ 468 if (info->state->line == siccuart_cons.index) { 469 if (!info->sysrq) { 470 info->sysrq = jiffies + HZ*5; 471 goto ignore_char; 472 } 473 } 474#endif 475 } else if (rsr & _LSR_PE_MASK) 476 icount->parity++; 477 else if (rsr & _LSR_FE_MASK) 478 icount->frame++; 479 if (rsr & _LSR_OE_MASK) 480 icount->overrun++; 481 482 if (rsr & info->ignore_status_mask) { 483 if (++ignored > 100) 484 goto out; 485 goto ignore_char; 486 } 487 rsr &= info->read_status_mask; 488 489 if (rsr & _LSR_LB_BREAK) 490 flg = TTY_BREAK; 491 else if (rsr & _LSR_PE_MASK) 492 flg = TTY_PARITY; 493 else if (rsr & _LSR_FE_MASK) 494 flg = TTY_FRAME; 495 496 if (rsr & _LSR_OE_MASK) { 497 /* 498 * CHECK: does overrun affect the current character? 499 * ASSUMPTION: it does not. 500 */ 501 *tty->flip.flag_buf_ptr++ = flg; 502 *tty->flip.char_buf_ptr++ = ch; 503 tty->flip.count++; 504 if (tty->flip.count >= TTY_FLIPBUF_SIZE) 505 goto ignore_char; 506 ch = 0; 507 flg = TTY_OVERRUN; 508 } 509#ifdef SUPPORT_SYSRQ 510 info->sysrq = 0; 511#endif 512 goto error_return; 513} 514 515static void siccuart_tx_chars(struct SICC_info *info) 516{ 517 struct SICC_port *port = info->port; 518 int count; 519 unsigned char status; 520 521 522 if (info->x_char) { 523 writeb(info->x_char, port->uart_base+ BL_SICC_TBR); 524 info->state->icount.tx++; 525 info->x_char = 0; 526 return; 527 } 528 if (info->xmit.head == info->xmit.tail 529 || info->tty->stopped 530 || info->tty->hw_stopped) { 531 siccuart_disable_tx_interrupt(info); 532 writeb(status&(~_LSR_RBR_MASK),port->uart_base+BL_SICC_LSR); 533 return; 534 } 535 536 count = port->fifosize; 537 do { 538 writeb(info->xmit.buf[info->xmit.tail], port->uart_base+ BL_SICC_TBR); 539 info->xmit.tail = (info->xmit.tail + 1) & (SICC_XMIT_SIZE - 1); 540 info->state->icount.tx++; 541 if (info->xmit.head == info->xmit.tail) 542 break; 543 } while (--count > 0); 544 545 if (CIRC_CNT(info->xmit.head, 546 info->xmit.tail, 547 SICC_XMIT_SIZE) < WAKEUP_CHARS) 548 siccuart_event(info, EVT_WRITE_WAKEUP); 549 550 if (info->xmit.head == info->xmit.tail) { 551 siccuart_disable_tx_interrupt(info); 552 } 553} 554 555 556static irqreturn_t siccuart_int_rx(int irq, void *dev_id) 557{ 558 struct SICC_info *info = dev_id; 559 siccuart_rx_chars(info) 560 return IRQ_HANDLED; 561} 562 563 564static irqreturn_t siccuart_int_tx(int irq, void *dev_id) 565{ 566 struct SICC_info *info = dev_id; 567 siccuart_tx_chars(info); 568 return IRQ_HANDLED; 569} 570 571static void siccuart_tasklet_action(unsigned long data) 572{ 573 struct SICC_info *info = (struct SICC_info *)data; 574 struct tty_struct *tty; 575 576 tty = info->tty; 577 if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event)) 578 return; 579 580 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 581 tty->ldisc.write_wakeup) 582 (tty->ldisc.write_wakeup)(tty); 583 wake_up_interruptible(&tty->write_wait); 584} 585 586static int siccuart_startup(struct SICC_info *info) 587{ 588 unsigned long flags; 589 unsigned long page; 590 int retval = 0; 591 592 if (info->flags & ASYNC_INITIALIZED) { 593 return 0; 594 } 595 596 page = get_zeroed_page(GFP_KERNEL); 597 if (!page) 598 return -ENOMEM; 599 600 if (info->port->uart_base == 0) 601 info->port->uart_base = (int)ioremap(info->port->uart_base_phys, PAGE_SIZE); 602 if (info->port->uart_base == 0) { 603 free_page(page); 604 return -ENOMEM; 605 } 606 607 /* lock access to info while doing setup */ 608 spin_lock_irqsave(&info->state->sicc_lock,flags); 609 610 if (info->xmit.buf) 611 free_page(page); 612 else 613 info->xmit.buf = (unsigned char *) page; 614 615 616 info->mctrl = 0; 617 if (info->tty->termios->c_cflag & CBAUD) 618 info->mctrl = TIOCM_RTS | TIOCM_DTR; 619 info->port->set_mctrl(info->port, info->mctrl); 620 621 /* 622 * initialise the old status of the modem signals 623 */ 624 info->old_status = 0; // UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY; 625 626 627 if (info->tty) 628 clear_bit(TTY_IO_ERROR, &info->tty->flags); 629 info->xmit.head = info->xmit.tail = 0; 630 631 /* 632 * Set up the tty->alt_speed kludge 633 */ 634 if (info->tty) { 635 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 636 info->tty->alt_speed = 57600; 637 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 638 info->tty->alt_speed = 115200; 639 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 640 info->tty->alt_speed = 230400; 641 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 642 info->tty->alt_speed = 460800; 643 } 644 645 646 writeb( 0x00, info->port->uart_base + BL_SICC_IrCR ); // disable IrDA 647 648 649 /* 650 * and set the speed of the serial port 651 */ 652 siccuart_change_speed(info, 0); 653 654 // enable rx/tx ports 655 writeb(_RCR_ER_ENABLE /*| _RCR_PME_HARD*/, info->port->uart_base + BL_SICC_RCR); 656 writeb(_TxCR_ET_ENABLE , info->port->uart_base + BL_SICC_TxCR); 657 658 readb(info->port->uart_base + BL_SICC_RBR); // clear rx port 659 660 writeb(0xf8, info->port->uart_base + BL_SICC_LSR); /* reset bits 0-4 of LSR */ 661 662 /* 663 * Finally, enable interrupts 664 */ 665 666 /* 667 * Allocate the IRQ 668 */ 669 retval = request_irq(info->port->irqrx, siccuart_int_rx, 0, "SICC rx", info); 670 if (retval) { 671 if (capable(CAP_SYS_ADMIN)) { 672 if (info->tty) 673 set_bit(TTY_IO_ERROR, &info->tty->flags); 674 retval = 0; 675 } 676 goto errout; 677 } 678 retval = request_irq(info->port->irqtx, siccuart_int_tx, 0, "SICC tx", info); 679 if (retval) { 680 if (capable(CAP_SYS_ADMIN)) { 681 if (info->tty) 682 set_bit(TTY_IO_ERROR, &info->tty->flags); 683 retval = 0; 684 } 685 free_irq(info->port->irqrx, info); 686 goto errout; 687 } 688 689 siccuart_enable_rx_interrupt(info); 690 691 info->flags |= ASYNC_INITIALIZED; 692 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 693 return 0; 694 695 696errout: 697 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 698 return retval; 699} 700 701/* 702 * This routine will shutdown a serial port; interrupts are disabled, and 703 * DTR is dropped if the hangup on close termio flag is on. 704 */ 705static void siccuart_shutdown(struct SICC_info *info) 706{ 707 unsigned long flags; 708 709 if (!(info->flags & ASYNC_INITIALIZED)) 710 return; 711 712 /* lock while shutting down port */ 713 spin_lock_irqsave(&info->state->sicc_lock,flags); /* Disable interrupts */ 714 715 /* 716 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq 717 * here so the queue might never be woken up 718 */ 719 wake_up_interruptible(&info->delta_msr_wait); 720 721 /* 722 * disable all interrupts, disable the port 723 */ 724 siccuart_disable_rx_interrupt(info); 725 siccuart_disable_tx_interrupt(info); 726 727 /* 728 * Free the IRQ 729 */ 730 free_irq(info->port->irqtx, info); 731 free_irq(info->port->irqrx, info); 732 733 if (info->xmit.buf) { 734 unsigned long pg = (unsigned long) info->xmit.buf; 735 info->xmit.buf = NULL; 736 free_page(pg); 737 } 738 739 740 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) 741 info->mctrl &= ~(TIOCM_DTR|TIOCM_RTS); 742 info->port->set_mctrl(info->port, info->mctrl); 743 744 /* kill off our tasklet */ 745 tasklet_kill(&info->tlet); 746 if (info->tty) 747 set_bit(TTY_IO_ERROR, &info->tty->flags); 748 749 info->flags &= ~ASYNC_INITIALIZED; 750 751 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 752} 753 754 755static void siccuart_change_speed(struct SICC_info *info, struct termios *old_termios) 756{ 757 unsigned int lcr_h, baud, quot, cflag, old_rcr, old_tcr, bits; 758 unsigned long flags; 759 760 if (!info->tty || !info->tty->termios) 761 return; 762 763 cflag = info->tty->termios->c_cflag; 764 765 pr_debug("siccuart_set_cflag(0x%x) called\n", cflag); 766 /* byte size and parity */ 767 switch (cflag & CSIZE) { 768 case CS7: lcr_h = _LCR_PE_DISABLE | _LCR_DB_7_BITS | _LCR_SB_1_BIT; bits = 9; break; 769 default: lcr_h = _LCR_PE_DISABLE | _LCR_DB_8_BITS | _LCR_SB_1_BIT; bits = 10; break; // CS8 770 } 771 if (cflag & CSTOPB) { 772 lcr_h |= _LCR_SB_2_BIT; 773 bits ++; 774 } 775 if (cflag & PARENB) { 776 lcr_h |= _LCR_PE_ENABLE; 777 bits++; 778 if (!(cflag & PARODD)) 779 lcr_h |= _LCR_PTY_ODD; 780 else 781 lcr_h |= _LCR_PTY_EVEN; 782 } 783 784 do { 785 /* Determine divisor based on baud rate */ 786 baud = tty_get_baud_rate(info->tty); 787 if (!baud) 788 baud = 9600; 789 790 791 { 792 // here is ppc403SetBaud(com_port, baud); 793 unsigned long divisor, clockSource, temp; 794 795 /* Ensure CICCR[7] is 0 to select Internal Baud Clock */ 796 powerpcMtcic_cr((unsigned long)(powerpcMfcic_cr() & 0xFEFFFFFF)); 797 798 /* Determine Internal Baud Clock Frequency */ 799 /* powerpcMfclkgpcr() reads DCR 0x120 - the*/ 800 /* SCCR (Serial Clock Control Register) on Vesta */ 801 temp = powerpcMfclkgpcr(); 802 803 if(temp & 0x00000080) { 804 clockSource = 324000000; 805 } 806 else { 807 clockSource = 216000000; 808 } 809 clockSource = clockSource/(unsigned long)((temp&0x00FC0000)>>18); 810 divisor = clockSource/(16*baud) - 1; 811 /* divisor has only 12 bits of resolution */ 812 if(divisor>0x00000FFF){ 813 divisor=0x00000FFF; 814 } 815 816 quot = divisor; 817 } 818 819 if (baud == 38400 && 820 ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) 821 quot = info->state->custom_divisor; 822 823 if (!quot && old_termios) { 824 info->tty->termios->c_cflag &= ~CBAUD; 825 info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); 826 old_termios = NULL; 827 } 828 } while (quot == 0 && old_termios); 829 830 /* As a last resort, if the quotient is zero, default to 9600 bps */ 831 if (!quot) 832 quot = (info->port->uartclk / (16 * 9600)) - 1; 833 834 info->timeout = info->port->fifosize * HZ * bits / baud; 835 info->timeout += HZ/50; /* Add .02 seconds of slop */ 836 837 if (cflag & CRTSCTS) 838 info->flags |= ASYNC_CTS_FLOW; 839 else 840 info->flags &= ~ASYNC_CTS_FLOW; 841 if (cflag & CLOCAL) 842 info->flags &= ~ASYNC_CHECK_CD; 843 else 844 info->flags |= ASYNC_CHECK_CD; 845 846 /* 847 * Set up parity check flag 848 */ 849#define RELEVENT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) 850 851 info->read_status_mask = _LSR_OE_MASK; 852 if (I_INPCK(info->tty)) 853 info->read_status_mask |= _LSR_FE_MASK | _LSR_PE_MASK; 854 if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 855 info->read_status_mask |= _LSR_LB_MASK; 856 857 /* 858 * Characters to ignore 859 */ 860 info->ignore_status_mask = 0; 861 if (I_IGNPAR(info->tty)) 862 info->ignore_status_mask |= _LSR_FE_MASK | _LSR_PE_MASK; 863 if (I_IGNBRK(info->tty)) { 864 info->ignore_status_mask |= _LSR_LB_MASK; 865 /* 866 * If we're ignoring parity and break indicators, 867 * ignore overruns to (for real raw support). 868 */ 869 if (I_IGNPAR(info->tty)) 870 info->ignore_status_mask |= _LSR_OE_MASK; 871 } 872 873 /* disable interrupts while reading and clearing registers */ 874 spin_lock_irqsave(&info->state->sicc_lock,flags); 875 876 old_rcr = readb(info->port->uart_base + BL_SICC_RCR); 877 old_tcr = readb(info->port->uart_base + BL_SICC_TxCR); 878 879 880 writeb(0, info->port->uart_base + BL_SICC_RCR); 881 writeb(0, info->port->uart_base + BL_SICC_TxCR); 882 883 /*RLBtrace (&ppc403Chan0, 0x2000000c, 0, 0);*/ 884 885 886 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 887 888 889 /* Set baud rate */ 890 writeb((quot & 0x00000F00)>>8, info->port->uart_base + BL_SICC_BRDH ); 891 writeb( quot & 0x00000FF, info->port->uart_base + BL_SICC_BRDL ); 892 893 /* Set CTL2 reg to use external clock (ExtClk) and enable FIFOs. */ 894 /* For now, do NOT use FIFOs since 403 UART did not have this */ 895 /* capability and this driver was inherited from 403UART. */ 896 writeb(_CTL2_EXTERN, info->port->uart_base + BL_SICC_CTL2); 897 898 writeb(lcr_h, info->port->uart_base + BL_SICC_LCR); 899 900 writeb(old_rcr, info->port->uart_base + BL_SICC_RCR); // restore rcr 901 writeb(old_tcr, info->port->uart_base + BL_SICC_TxCR); // restore txcr 902 903} 904 905 906static void siccuart_put_char(struct tty_struct *tty, u_char ch) 907{ 908 struct SICC_info *info = tty->driver_data; 909 unsigned long flags; 910 911 if (!tty || !info->xmit.buf) 912 return; 913 914 /* lock info->xmit while adding character to tx buffer */ 915 spin_lock_irqsave(&info->state->sicc_lock,flags); 916 if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SICC_XMIT_SIZE) != 0) { 917 info->xmit.buf[info->xmit.head] = ch; 918 info->xmit.head = (info->xmit.head + 1) & (SICC_XMIT_SIZE - 1); 919 } 920 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 921} 922 923static void siccuart_flush_chars(struct tty_struct *tty) 924{ 925 struct SICC_info *info = tty->driver_data; 926 unsigned long flags; 927 928 if (info->xmit.head == info->xmit.tail 929 || tty->stopped 930 || tty->hw_stopped 931 || !info->xmit.buf) 932 return; 933 934 /* disable interrupts while transmitting characters */ 935 spin_lock_irqsave(&info->state->sicc_lock,flags); 936 siccuart_enable_tx_interrupt(info); 937 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 938} 939 940static int siccuart_write(struct tty_struct *tty, 941 const u_char * buf, int count) 942{ 943 struct SICC_info *info = tty->driver_data; 944 unsigned long flags; 945 int c, ret = 0; 946 947 if (!tty || !info->xmit.buf || !tmp_buf) 948 return 0; 949 950 /* lock info->xmit while removing characters from buffer */ 951 spin_lock_irqsave(&info->state->sicc_lock,flags); 952 while (1) { 953 c = CIRC_SPACE_TO_END(info->xmit.head, 954 info->xmit.tail, 955 SICC_XMIT_SIZE); 956 if (count < c) 957 c = count; 958 if (c <= 0) 959 break; 960 memcpy(info->xmit.buf + info->xmit.head, buf, c); 961 info->xmit.head = (info->xmit.head + c) & 962 (SICC_XMIT_SIZE - 1); 963 buf += c; 964 count -= c; 965 ret += c; 966 } 967 if (info->xmit.head != info->xmit.tail 968 && !tty->stopped 969 && !tty->hw_stopped) 970 siccuart_enable_tx_interrupt(info); 971 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 972 return ret; 973} 974 975static int siccuart_write_room(struct tty_struct *tty) 976{ 977 struct SICC_info *info = tty->driver_data; 978 979 return CIRC_SPACE(info->xmit.head, info->xmit.tail, SICC_XMIT_SIZE); 980} 981 982static int siccuart_chars_in_buffer(struct tty_struct *tty) 983{ 984 struct SICC_info *info = tty->driver_data; 985 986 return CIRC_CNT(info->xmit.head, info->xmit.tail, SICC_XMIT_SIZE); 987} 988 989static void siccuart_flush_buffer(struct tty_struct *tty) 990{ 991 struct SICC_info *info = tty->driver_data; 992 unsigned long flags; 993 994 pr_debug("siccuart_flush_buffer(%d) called\n", tty->index); 995 /* lock info->xmit while zeroing buffer counts */ 996 spin_lock_irqsave(&info->state->sicc_lock,flags); 997 info->xmit.head = info->xmit.tail = 0; 998 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 999 wake_up_interruptible(&tty->write_wait); 1000 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 1001 tty->ldisc.write_wakeup) 1002 (tty->ldisc.write_wakeup)(tty); 1003} 1004 1005/* 1006 * This function is used to send a high-priority XON/XOFF character to 1007 * the device 1008 */ 1009static void siccuart_send_xchar(struct tty_struct *tty, char ch) 1010{ 1011 struct SICC_info *info = tty->driver_data; 1012 1013 info->x_char = ch; 1014 if (ch) 1015 siccuart_enable_tx_interrupt(info); 1016} 1017 1018static void siccuart_throttle(struct tty_struct *tty) 1019{ 1020 struct SICC_info *info = tty->driver_data; 1021 unsigned long flags; 1022 1023 if (I_IXOFF(tty)) 1024 siccuart_send_xchar(tty, STOP_CHAR(tty)); 1025 1026 if (tty->termios->c_cflag & CRTSCTS) { 1027 /* disable interrupts while setting modem control lines */ 1028 spin_lock_irqsave(&info->state->sicc_lock,flags); 1029 info->mctrl &= ~TIOCM_RTS; 1030 info->port->set_mctrl(info->port, info->mctrl); 1031 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1032 } 1033} 1034 1035static void siccuart_unthrottle(struct tty_struct *tty) 1036{ 1037 struct SICC_info *info = (struct SICC_info *) tty->driver_data; 1038 unsigned long flags; 1039 1040 if (I_IXOFF(tty)) { 1041 if (info->x_char) 1042 info->x_char = 0; 1043 else 1044 siccuart_send_xchar(tty, START_CHAR(tty)); 1045 } 1046 1047 if (tty->termios->c_cflag & CRTSCTS) { 1048 /* disable interrupts while setting modem control lines */ 1049 spin_lock_irqsave(&info->state->sicc_lock,flags); 1050 info->mctrl |= TIOCM_RTS; 1051 info->port->set_mctrl(info->port, info->mctrl); 1052 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1053 } 1054} 1055 1056static int get_serial_info(struct SICC_info *info, struct serial_struct *retinfo) 1057{ 1058 struct SICC_state *state = info->state; 1059 struct SICC_port *port = info->port; 1060 struct serial_struct tmp; 1061 1062 memset(&tmp, 0, sizeof(tmp)); 1063 tmp.type = 0; 1064 tmp.line = state->line; 1065 tmp.port = port->uart_base; 1066 if (HIGH_BITS_OFFSET) 1067 tmp.port_high = port->uart_base >> HIGH_BITS_OFFSET; 1068 tmp.irq = port->irqrx; 1069 tmp.flags = 0; 1070 tmp.xmit_fifo_size = port->fifosize; 1071 tmp.baud_base = port->uartclk / 16; 1072 tmp.close_delay = state->close_delay; 1073 tmp.closing_wait = state->closing_wait; 1074 tmp.custom_divisor = state->custom_divisor; 1075 1076 if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 1077 return -EFAULT; 1078 return 0; 1079} 1080 1081static int set_serial_info(struct SICC_info *info, 1082 struct serial_struct *newinfo) 1083{ 1084 struct serial_struct new_serial; 1085 struct SICC_state *state, old_state; 1086 struct SICC_port *port; 1087 unsigned long new_port; 1088 unsigned int i, change_irq, change_port; 1089 int retval = 0; 1090 1091 if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) 1092 return -EFAULT; 1093 1094 state = info->state; 1095 old_state = *state; 1096 port = info->port; 1097 1098 new_port = new_serial.port; 1099 if (HIGH_BITS_OFFSET) 1100 new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; 1101 1102 change_irq = new_serial.irq != port->irqrx; 1103 change_port = new_port != port->uart_base; 1104 1105 if (!capable(CAP_SYS_ADMIN)) { 1106 if (change_irq || change_port || 1107 (new_serial.baud_base != port->uartclk / 16) || 1108 (new_serial.close_delay != state->close_delay) || 1109 (new_serial.xmit_fifo_size != port->fifosize) || 1110 ((new_serial.flags & ~ASYNC_USR_MASK) != 1111 (state->flags & ~ASYNC_USR_MASK))) 1112 return -EPERM; 1113 state->flags = ((state->flags & ~ASYNC_USR_MASK) | 1114 (new_serial.flags & ASYNC_USR_MASK)); 1115 info->flags = ((info->flags & ~ASYNC_USR_MASK) | 1116 (new_serial.flags & ASYNC_USR_MASK)); 1117 state->custom_divisor = new_serial.custom_divisor; 1118 goto check_and_exit; 1119 } 1120 1121 if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 1122 (new_serial.baud_base < 9600)) 1123 return -EINVAL; 1124 1125 if (new_serial.type && change_port) { 1126 for (i = 0; i < SERIAL_SICC_NR; i++) 1127 if ((port != sicc_ports + i) && 1128 sicc_ports[i].uart_base != new_port) 1129 return -EADDRINUSE; 1130 } 1131 1132 if ((change_port || change_irq) && (state->count > 1)) 1133 return -EBUSY; 1134 1135 /* 1136 * OK, past this point, all the error checking has been done. 1137 * At this point, we start making changes..... 1138 */ 1139 port->uartclk = new_serial.baud_base * 16; 1140 state->flags = ((state->flags & ~ASYNC_FLAGS) | 1141 (new_serial.flags & ASYNC_FLAGS)); 1142 info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | 1143 (info->flags & ASYNC_INTERNAL_FLAGS)); 1144 state->custom_divisor = new_serial.custom_divisor; 1145 state->close_delay = msecs_to_jiffies(10 * new_serial.close_delay); 1146 state->closing_wait = msecs_to_jiffies(10 * new_serial.closing_wait); 1147 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1148 port->fifosize = new_serial.xmit_fifo_size; 1149 1150 if (change_port || change_irq) { 1151 /* 1152 * We need to shutdown the serial port at the old 1153 * port/irq combination. 1154 */ 1155 siccuart_shutdown(info); 1156 port->irqrx = new_serial.irq; 1157 port->uart_base = new_port; 1158 } 1159 1160check_and_exit: 1161 if (!port->uart_base) 1162 return 0; 1163 if (info->flags & ASYNC_INITIALIZED) { 1164 if ((old_state.flags & ASYNC_SPD_MASK) != 1165 (state->flags & ASYNC_SPD_MASK) || 1166 (old_state.custom_divisor != state->custom_divisor)) { 1167 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 1168 info->tty->alt_speed = 57600; 1169 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 1170 info->tty->alt_speed = 115200; 1171 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 1172 info->tty->alt_speed = 230400; 1173 if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 1174 info->tty->alt_speed = 460800; 1175 siccuart_change_speed(info, NULL); 1176 } 1177 } else 1178 retval = siccuart_startup(info); 1179 return retval; 1180} 1181 1182 1183/* 1184 * get_lsr_info - get line status register info 1185 */ 1186static int get_lsr_info(struct SICC_info *info, unsigned int *value) 1187{ 1188 unsigned int result, status; 1189 unsigned long flags; 1190 1191 /* disable interrupts while reading status from port */ 1192 spin_lock_irqsave(&info->state->sicc_lock,flags); 1193 status = readb(info->port->uart_base + BL_SICC_LSR); 1194 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1195 result = status & _LSR_TSR_EMPTY ? TIOCSER_TEMT : 0; 1196 1197 /* 1198 * If we're about to load something into the transmit 1199 * register, we'll pretend the transmitter isn't empty to 1200 * avoid a race condition (depending on when the transmit 1201 * interrupt happens). 1202 */ 1203 if (info->x_char || 1204 ((CIRC_CNT(info->xmit.head, info->xmit.tail, 1205 SICC_XMIT_SIZE) > 0) && 1206 !info->tty->stopped && !info->tty->hw_stopped)) 1207 result &= TIOCSER_TEMT; 1208 1209 return put_user(result, value); 1210} 1211 1212static int get_modem_info(struct SICC_info *info, unsigned int *value) 1213{ 1214 unsigned int result = info->mctrl; 1215 1216 return put_user(result, value); 1217} 1218 1219static int set_modem_info(struct SICC_info *info, unsigned int cmd, 1220 unsigned int *value) 1221{ 1222 unsigned int arg, old; 1223 unsigned long flags; 1224 1225 if (get_user(arg, value)) 1226 return -EFAULT; 1227 1228 old = info->mctrl; 1229 switch (cmd) { 1230 case TIOCMBIS: 1231 info->mctrl |= arg; 1232 break; 1233 1234 case TIOCMBIC: 1235 info->mctrl &= ~arg; 1236 break; 1237 1238 case TIOCMSET: 1239 info->mctrl = arg; 1240 break; 1241 1242 default: 1243 return -EINVAL; 1244 } 1245 /* disable interrupts while setting modem control lines */ 1246 spin_lock_irqsave(&info->state->sicc_lock,flags); 1247 if (old != info->mctrl) 1248 info->port->set_mctrl(info->port, info->mctrl); 1249 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1250 return 0; 1251} 1252 1253static void siccuart_break_ctl(struct tty_struct *tty, int break_state) 1254{ 1255 struct SICC_info *info = tty->driver_data; 1256 unsigned long flags; 1257 unsigned int lcr_h; 1258 1259 1260 /* disable interrupts while setting break state */ 1261 spin_lock_irqsave(&info->state->sicc_lock,flags); 1262 lcr_h = readb(info->port + BL_SICC_LSR); 1263 if (break_state == -1) 1264 lcr_h |= _LSR_LB_MASK; 1265 else 1266 lcr_h &= ~_LSR_LB_MASK; 1267 writeb(lcr_h, info->port + BL_SICC_LSRS); 1268 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1269} 1270 1271static int siccuart_ioctl(struct tty_struct *tty, struct file *file, 1272 unsigned int cmd, unsigned long arg) 1273{ 1274 struct SICC_info *info = tty->driver_data; 1275 struct SICC_icount cnow; 1276 struct serial_icounter_struct icount; 1277 unsigned long flags; 1278 1279 if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && 1280 (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && 1281 (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { 1282 if (tty->flags & (1 << TTY_IO_ERROR)) 1283 return -EIO; 1284 } 1285 1286 switch (cmd) { 1287 case TIOCMGET: 1288 return get_modem_info(info, (unsigned int *)arg); 1289 case TIOCMBIS: 1290 case TIOCMBIC: 1291 case TIOCMSET: 1292 return set_modem_info(info, cmd, (unsigned int *)arg); 1293 case TIOCGSERIAL: 1294 return get_serial_info(info, 1295 (struct serial_struct *)arg); 1296 case TIOCSSERIAL: 1297 return set_serial_info(info, 1298 (struct serial_struct *)arg); 1299 case TIOCSERGETLSR: /* Get line status register */ 1300 return get_lsr_info(info, (unsigned int *)arg); 1301 /* 1302 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 1303 * - mask passed in arg for lines of interest 1304 * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) 1305 * Caller should use TIOCGICOUNT to see which one it was 1306 */ 1307 case TIOCMIWAIT: 1308 return 0; 1309 /* 1310 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 1311 * Return: write counters to the user passed counter struct 1312 * NB: both 1->0 and 0->1 transitions are counted except for 1313 * RI where only 0->1 is counted. 1314 */ 1315 case TIOCGICOUNT: 1316 /* disable interrupts while getting interrupt count */ 1317 spin_lock_irqsave(&info->state->sicc_lock,flags); 1318 cnow = info->state->icount; 1319 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1320 icount.cts = cnow.cts; 1321 icount.dsr = cnow.dsr; 1322 icount.rng = cnow.rng; 1323 icount.dcd = cnow.dcd; 1324 icount.rx = cnow.rx; 1325 icount.tx = cnow.tx; 1326 icount.frame = cnow.frame; 1327 icount.overrun = cnow.overrun; 1328 icount.parity = cnow.parity; 1329 icount.brk = cnow.brk; 1330 icount.buf_overrun = cnow.buf_overrun; 1331 1332 return copy_to_user((void *)arg, &icount, sizeof(icount)) 1333 ? -EFAULT : 0; 1334 1335 default: 1336 return -ENOIOCTLCMD; 1337 } 1338 return 0; 1339} 1340 1341static void siccuart_set_termios(struct tty_struct *tty, struct termios *old_termios) 1342{ 1343 struct SICC_info *info = tty->driver_data; 1344 unsigned long flags; 1345 unsigned int cflag = tty->termios->c_cflag; 1346 1347 if ((cflag ^ old_termios->c_cflag) == 0 && 1348 RELEVENT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) 1349 return; 1350 1351 siccuart_change_speed(info, old_termios); 1352 1353 /* Handle transition to B0 status */ 1354 if ((old_termios->c_cflag & CBAUD) && 1355 !(cflag & CBAUD)) { 1356 /* disable interrupts while setting break state */ 1357 spin_lock_irqsave(&info->state->sicc_lock,flags); 1358 info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR); 1359 info->port->set_mctrl(info->port, info->mctrl); 1360 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1361 } 1362 1363 /* Handle transition away from B0 status */ 1364 if (!(old_termios->c_cflag & CBAUD) && 1365 (cflag & CBAUD)) { 1366 /* disable interrupts while setting break state */ 1367 spin_lock_irqsave(&info->state->sicc_lock,flags); 1368 info->mctrl |= TIOCM_DTR; 1369 if (!(cflag & CRTSCTS) || 1370 !test_bit(TTY_THROTTLED, &tty->flags)) 1371 info->mctrl |= TIOCM_RTS; 1372 info->port->set_mctrl(info->port, info->mctrl); 1373 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1374 } 1375 1376 /* Handle turning off CRTSCTS */ 1377 if ((old_termios->c_cflag & CRTSCTS) && 1378 !(cflag & CRTSCTS)) { 1379 tty->hw_stopped = 0; 1380 siccuart_start(tty); 1381 } 1382 1383} 1384 1385static void siccuart_close(struct tty_struct *tty, struct file *filp) 1386{ 1387 struct SICC_info *info = tty->driver_data; 1388 struct SICC_state *state; 1389 unsigned long flags; 1390 1391 if (!info) 1392 return; 1393 1394 state = info->state; 1395 1396 //pr_debug("siccuart_close() called\n"); 1397 1398 /* lock tty->driver_data while closing port */ 1399 spin_lock_irqsave(&info->state->sicc_lock,flags); 1400 1401 if (tty_hung_up_p(filp)) { 1402 goto quick_close; 1403 } 1404 1405 if ((tty->count == 1) && (state->count != 1)) { 1406 /* 1407 * Uh, oh. tty->count is 1, which means that the tty 1408 * structure will be freed. state->count should always 1409 * be one in these conditions. If it's greater than 1410 * one, we've got real problems, since it means the 1411 * serial port won't be shutdown. 1412 */ 1413 printk("siccuart_close: bad serial port count; tty->count is 1, state->count is %d\n", state->count); 1414 state->count = 1; 1415 } 1416 if (--state->count < 0) { 1417 printk("rs_close: bad serial port count for %s: %d\n", tty->name, state->count); 1418 state->count = 0; 1419 } 1420 if (state->count) { 1421 goto quick_close; 1422 } 1423 info->flags |= ASYNC_CLOSING; 1424 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1425 /* 1426 * Now we wait for the transmit buffer to clear; and we notify 1427 * the line discipline to only process XON/XOFF characters. 1428 */ 1429 tty->closing = 1; 1430 if (info->state->closing_wait != ASYNC_CLOSING_WAIT_NONE) 1431 tty_wait_until_sent(tty, info->state->closing_wait); 1432 /* 1433 * At this point, we stop accepting input. To do this, we 1434 * disable the receive line status interrupts. 1435 */ 1436 if (info->flags & ASYNC_INITIALIZED) { 1437 siccuart_disable_rx_interrupt(info); 1438 /* 1439 * Before we drop DTR, make sure the UART transmitter 1440 * has completely drained; this is especially 1441 * important if there is a transmit FIFO! 1442 */ 1443 siccuart_wait_until_sent(tty, info->timeout); 1444 } 1445 siccuart_shutdown(info); 1446 if (tty->driver->flush_buffer) 1447 tty->driver->flush_buffer(tty); 1448 if (tty->ldisc.flush_buffer) 1449 tty->ldisc.flush_buffer(tty); 1450 tty->closing = 0; 1451 info->event = 0; 1452 info->tty = NULL; 1453 if (info->blocked_open) { 1454 if (info->state->close_delay) 1455 schedule_timeout_interruptible(info->state->close_delay); 1456 wake_up_interruptible(&info->open_wait); 1457 } 1458 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 1459 wake_up_interruptible(&info->close_wait); 1460 return; 1461 1462quick_close: 1463 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1464 return; 1465} 1466 1467static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout) 1468{ 1469 struct SICC_info *info = (struct SICC_info *) tty->driver_data; 1470 unsigned long char_time, expire; 1471 1472 if (info->port->fifosize == 0) 1473 return; 1474 1475 /* 1476 * Set the check interval to be 1/5 of the estimated time to 1477 * send a single character, and make it at least 1. The check 1478 * interval should also be less than the timeout. 1479 * 1480 * Note: we have to use pretty tight timings here to satisfy 1481 * the NIST-PCTS. 1482 */ 1483 char_time = (info->timeout - msecs_to_jiffies(20)) / info->port->fifosize; 1484 char_time = char_time / 5; 1485 if (char_time == 0) 1486 char_time = 1; 1487 1488 // Crazy!! sometimes the input arg 'timeout' can be negtive numbers :-( 1489 if (timeout >= 0 && timeout < char_time) 1490 char_time = timeout; 1491 /* 1492 * If the transmitter hasn't cleared in twice the approximate 1493 * amount of time to send the entire FIFO, it probably won't 1494 * ever clear. This assumes the UART isn't doing flow 1495 * control, which is currently the case. Hence, if it ever 1496 * takes longer than info->timeout, this is probably due to a 1497 * UART bug of some kind. So, we clamp the timeout parameter at 1498 * 2*info->timeout. 1499 */ 1500 if (!timeout || timeout > 2 * info->timeout) 1501 timeout = 2 * info->timeout; 1502 1503 expire = jiffies + timeout; 1504 pr_debug("siccuart_wait_until_sent(%d), jiff=%lu, expire=%lu char_time=%lu...\n", 1505 tty->index, jiffies, 1506 expire, char_time); 1507 while ((readb(info->port->uart_base + BL_SICC_LSR) & _LSR_TX_ALL) != _LSR_TX_ALL) { 1508 schedule_timeout_interruptible(char_time); 1509 if (signal_pending(current)) 1510 break; 1511 if (timeout && time_after(jiffies, expire)) 1512 break; 1513 } 1514 set_current_state(TASK_RUNNING); 1515} 1516 1517static void siccuart_hangup(struct tty_struct *tty) 1518{ 1519 struct SICC_info *info = tty->driver_data; 1520 struct SICC_state *state = info->state; 1521 1522 siccuart_flush_buffer(tty); 1523 if (info->flags & ASYNC_CLOSING) 1524 return; 1525 siccuart_shutdown(info); 1526 info->event = 0; 1527 state->count = 0; 1528 info->flags &= ~ASYNC_NORMAL_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 SICC_info *info) 1535{ 1536 DECLARE_WAITQUEUE(wait, current); 1537 struct SICC_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 non-blocking mode is set, or the port is not enabled, 1555 * then make the check up front and then exit. 1556 */ 1557 if ((filp->f_flags & O_NONBLOCK) || 1558 (tty->flags & (1 << TTY_IO_ERROR))) { 1559 info->flags |= ASYNC_NORMAL_ACTIVE; 1560 return 0; 1561 } 1562 1563 if (tty->termios->c_cflag & CLOCAL) 1564 do_clocal = 1; 1565 1566 /* 1567 * Block waiting for the carrier detect and the line to become 1568 * free (i.e., not in use by the callout). While we are in 1569 * this loop, state->count is dropped by one, so that 1570 * rs_close() knows when to free things. We restore it upon 1571 * exit, either normal or abnormal. 1572 */ 1573 retval = 0; 1574 add_wait_queue(&info->open_wait, &wait); 1575 /* lock while decrementing state->count */ 1576 spin_lock_irqsave(&info->state->sicc_lock,flags); 1577 if (!tty_hung_up_p(filp)) { 1578 extra_count = 1; 1579 state->count--; 1580 } 1581 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1582 info->blocked_open++; 1583 while (1) { 1584 /* disable interrupts while setting modem control lines */ 1585 spin_lock_irqsave(&info->state->sicc_lock,flags); 1586 if (tty->termios->c_cflag & CBAUD) { 1587 info->mctrl = TIOCM_DTR | TIOCM_RTS; 1588 info->port->set_mctrl(info->port, info->mctrl); 1589 } 1590 spin_unlock_irqrestore(&info->state->sicc_lock,flags); 1591 set_current_state(TASK_INTERRUPTIBLE); 1592 if (tty_hung_up_p(filp) || 1593 !(info->flags & ASYNC_INITIALIZED)) { 1594 if (info->flags & ASYNC_HUP_NOTIFY) 1595 retval = -EAGAIN; 1596 else 1597 retval = -ERESTARTSYS; 1598 break; 1599 } 1600 if (!(info->flags & ASYNC_CLOSING) && 1601 (do_clocal /*|| (UART_GET_FR(info->port) & SICC_UARTFR_DCD)*/)) 1602 break; 1603 if (signal_pending(current)) { 1604 retval = -ERESTARTSYS; 1605 break; 1606 } 1607 schedule(); 1608 } 1609 set_current_state(TASK_RUNNING); 1610 remove_wait_queue(&info->open_wait, &wait); 1611 if (extra_count) 1612 state->count++; 1613 info->blocked_open--; 1614 if (retval) 1615 return retval; 1616 info->flags |= ASYNC_NORMAL_ACTIVE; 1617 return 0; 1618} 1619 1620static struct SICC_info *siccuart_get(int line) 1621{ 1622 struct SICC_info *info; 1623 struct SICC_state *state = sicc_state + line; 1624 1625 state->count++; 1626 if (state->info) 1627 return state->info; 1628 info = kzalloc(sizeof(struct SICC_info), GFP_KERNEL); 1629 if (info) { 1630 init_waitqueue_head(&info->open_wait); 1631 init_waitqueue_head(&info->close_wait); 1632 init_waitqueue_head(&info->delta_msr_wait); 1633 info->flags = state->flags; 1634 info->state = state; 1635 info->port = sicc_ports + line; 1636 tasklet_init(&info->tlet, siccuart_tasklet_action, 1637 (unsigned long)info); 1638 } 1639 if (state->info) { 1640 kfree(info); 1641 return state->info; 1642 } 1643 state->info = info; 1644 return info; 1645} 1646 1647static int siccuart_open(struct tty_struct *tty, struct file *filp) 1648{ 1649 struct SICC_info *info; 1650 int retval, line = tty->index; 1651 1652 1653 // is this a line that we've got? 1654 if (line >= SERIAL_SICC_NR) { 1655 return -ENODEV; 1656 } 1657 1658 info = siccuart_get(line); 1659 if (!info) 1660 return -ENOMEM; 1661 1662 tty->driver_data = info; 1663 info->tty = tty; 1664 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1665 1666 /* 1667 * Make sure we have the temporary buffer allocated 1668 */ 1669 if (!tmp_buf) { 1670 unsigned long page = get_zeroed_page(GFP_KERNEL); 1671 if (tmp_buf) 1672 free_page(page); 1673 else if (!page) { 1674 return -ENOMEM; 1675 } 1676 tmp_buf = (u_char *)page; 1677 } 1678 1679 /* 1680 * If the port is in the middle of closing, bail out now. 1681 */ 1682 if (tty_hung_up_p(filp) || 1683 (info->flags & ASYNC_CLOSING)) { 1684 if (info->flags & ASYNC_CLOSING) 1685 interruptible_sleep_on(&info->close_wait); 1686 return -EAGAIN; 1687 } 1688 1689 /* 1690 * Start up the serial port 1691 */ 1692 retval = siccuart_startup(info); 1693 if (retval) { 1694 return retval; 1695 } 1696 1697 retval = block_til_ready(tty, filp, info); 1698 if (retval) { 1699 return retval; 1700 } 1701 1702#ifdef CONFIG_SERIAL_SICC_CONSOLE 1703 if (siccuart_cons.cflag && siccuart_cons.index == line) { 1704 tty->termios->c_cflag = siccuart_cons.cflag; 1705 siccuart_cons.cflag = 0; 1706 siccuart_change_speed(info, NULL); 1707 } 1708#endif 1709 return 0; 1710} 1711 1712static const struct tty_operations sicc_ops = { 1713 .open = siccuart_open, 1714 .close = siccuart_close, 1715 .write = siccuart_write, 1716 .put_char = siccuart_put_char, 1717 .flush_chars = siccuart_flush_chars, 1718 .write_room = siccuart_write_room, 1719 .chars_in_buffer = siccuart_chars_in_buffer, 1720 .flush_buffer = siccuart_flush_buffer, 1721 .ioctl = siccuart_ioctl, 1722 .throttle = siccuart_throttle, 1723 .unthrottle = siccuart_unthrottle, 1724 .send_xchar = siccuart_send_xchar, 1725 .set_termios = siccuart_set_termios, 1726 .stop = siccuart_stop, 1727 .start = siccuart_start, 1728 .hangup = siccuart_hangup, 1729 .break_ctl = siccuart_break_ctl, 1730 .wait_until_sent = siccuart_wait_until_sent, 1731}; 1732 1733int __init siccuart_init(void) 1734{ 1735 int i; 1736 siccnormal_driver = alloc_tty_driver(SERIAL_SICC_NR); 1737 if (!siccnormal_driver) 1738 return -ENOMEM; 1739 printk("IBM Vesta SICC serial port driver V 0.1 by Yudong Yang and Yi Ge / IBM CRL .\n"); 1740 siccnormal_driver->driver_name = "serial_sicc"; 1741 siccnormal_driver->owner = THIS_MODULE; 1742 siccnormal_driver->name = SERIAL_SICC_NAME; 1743 siccnormal_driver->major = SERIAL_SICC_MAJOR; 1744 siccnormal_driver->minor_start = SERIAL_SICC_MINOR; 1745 siccnormal_driver->type = TTY_DRIVER_TYPE_SERIAL; 1746 siccnormal_driver->subtype = SERIAL_TYPE_NORMAL; 1747 siccnormal_driver->init_termios = tty_std_termios; 1748 siccnormal_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 1749 siccnormal_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 1750 tty_set_operations(siccnormal_driver, &sicc_ops); 1751 1752 if (tty_register_driver(siccnormal_driver)) 1753 panic("Couldn't register SICC serial driver\n"); 1754 1755 for (i = 0; i < SERIAL_SICC_NR; i++) { 1756 struct SICC_state *state = sicc_state + i; 1757 state->line = i; 1758 state->close_delay = msecs_to_jiffies(500); 1759 state->closing_wait = 30 * HZ; 1760 spin_lock_init(&state->sicc_lock); 1761 } 1762 1763 1764 return 0; 1765} 1766 1767__initcall(siccuart_init); 1768 1769#ifdef CONFIG_SERIAL_SICC_CONSOLE 1770/************** console driver *****************/ 1771 1772#ifdef used_and_not_const_char_pointer 1773static int siccuart_console_read(struct console *co, const char *s, u_int count) 1774{ 1775 struct SICC_port *port = &sicc_ports[co->index]; 1776 unsigned int status; 1777 char *w; 1778 int c; 1779 1780 pr_debug("siccuart_console_read() called\n"); 1781 1782 c = 0; 1783 w = s; 1784 while (c < count) { 1785 if(readb(port->uart_base + BL_SICC_LSR) & _LSR_RBR_FULL) { 1786 *w++ = readb(port->uart_base + BL_SICC_RBR); 1787 c++; 1788 } else { 1789 // nothing more to get, return 1790 return c; 1791 } 1792 } 1793 // return the count 1794 return c; 1795} 1796#endif 1797 1798/* 1799 * Print a string to the serial port trying not to disturb 1800 * any possible real use of the port... 1801 * 1802 * The console_lock must be held when we get here. 1803 */ 1804static void siccuart_console_write(struct console *co, const char *s, u_int count) 1805{ 1806 struct SICC_port *port = &sicc_ports[co->index]; 1807 unsigned int old_cr; 1808 int i; 1809 1810 /* 1811 * First save the CR then disable the interrupts 1812 */ 1813 old_cr = readb(port->uart_base + BL_SICC_TxCR); 1814 writeb(old_cr & ~_TxCR_DME_MASK, port->uart_base + BL_SICC_TxCR); 1815 1816 /* 1817 * Now, do each character 1818 */ 1819 for (i = 0; i < count; i++) { 1820 while ((readb(port->uart_base + BL_SICC_LSR)&_LSR_TX_ALL) != _LSR_TX_ALL); 1821 writeb(s[i], port->uart_base + BL_SICC_TBR); 1822 if (s[i] == '\n') { 1823 while ((readb(port->uart_base + BL_SICC_LSR)&_LSR_TX_ALL) != _LSR_TX_ALL); 1824 writeb('\r', port->uart_base + BL_SICC_TBR); 1825 } 1826 } 1827 1828 /* 1829 * Finally, wait for transmitter to become empty 1830 * and restore the TCR 1831 */ 1832 while ((readb(port->uart_base + BL_SICC_LSR)&_LSR_TX_ALL) != _LSR_TX_ALL); 1833 writeb(old_cr, port->uart_base + BL_SICC_TxCR); 1834} 1835 1836/* 1837 * Receive character from the serial port 1838 */ 1839static int siccuart_console_wait_key(struct console *co) 1840{ 1841 struct SICC_port *port = &sicc_ports[co->index]; 1842 int c; 1843 1844 while(!(readb(port->uart_base + BL_SICC_LSR) & _LSR_RBR_FULL)); 1845 c = readb(port->uart_base + BL_SICC_RBR); 1846 return c; 1847} 1848 1849static struct tty_driver *siccuart_console_device(struct console *c, int *index) 1850{ 1851 *index = c->index; 1852 return siccnormal_driver; 1853} 1854 1855static int __init siccuart_console_setup(struct console *co, char *options) 1856{ 1857 struct SICC_port *port; 1858 int baud = 9600; 1859 int bits = 8; 1860 int parity = 'n'; 1861 u_int cflag = CREAD | HUPCL | CLOCAL; 1862 u_int lcr_h, quot; 1863 1864 1865 if (co->index >= SERIAL_SICC_NR) 1866 co->index = 0; 1867 1868 port = &sicc_ports[co->index]; 1869 1870 if (port->uart_base == 0) 1871 port->uart_base = (int)ioremap(port->uart_base_phys, PAGE_SIZE); 1872 1873 if (options) { 1874 char *s = options; 1875 baud = simple_strtoul(s, NULL, 10); 1876 while (*s >= '0' && *s <= '9') 1877 s++; 1878 if (*s) parity = *s++; 1879 if (*s) bits = *s - '0'; 1880 } 1881 1882 /* 1883 * Now construct a cflag setting. 1884 */ 1885 switch (baud) { 1886 case 1200: cflag |= B1200; break; 1887 case 2400: cflag |= B2400; break; 1888 case 4800: cflag |= B4800; break; 1889 default: cflag |= B9600; baud = 9600; break; 1890 case 19200: cflag |= B19200; break; 1891 case 38400: cflag |= B38400; break; 1892 case 57600: cflag |= B57600; break; 1893 case 115200: cflag |= B115200; break; 1894 } 1895 switch (bits) { 1896 case 7: cflag |= CS7; lcr_h = _LCR_PE_DISABLE | _LCR_DB_7_BITS | _LCR_SB_1_BIT; break; 1897 default: cflag |= CS8; lcr_h = _LCR_PE_DISABLE | _LCR_DB_8_BITS | _LCR_SB_1_BIT; break; 1898 } 1899 switch (parity) { 1900 case 'o': 1901 case 'O': cflag |= PARODD; lcr_h |= _LCR_PTY_ODD; break; 1902 case 'e': 1903 case 'E': cflag |= PARENB; lcr_h |= _LCR_PE_ENABLE | _LCR_PTY_ODD; break; 1904 } 1905 1906 co->cflag = cflag; 1907 1908 1909 { 1910 // a copy of is inserted here ppc403SetBaud(com_port, (int)9600); 1911 unsigned long divisor, clockSource, temp; 1912 unsigned int rate = baud; 1913 1914 /* Ensure CICCR[7] is 0 to select Internal Baud Clock */ 1915 powerpcMtcic_cr((unsigned long)(powerpcMfcic_cr() & 0xFEFFFFFF)); 1916 1917 /* Determine Internal Baud Clock Frequency */ 1918 /* powerpcMfclkgpcr() reads DCR 0x120 - the*/ 1919 /* SCCR (Serial Clock Control Register) on Vesta */ 1920 temp = powerpcMfclkgpcr(); 1921 1922 if(temp & 0x00000080) { 1923 clockSource = 324000000; 1924 } 1925 else { 1926 clockSource = 216000000; 1927 } 1928 clockSource = clockSource/(unsigned long)((temp&0x00FC0000)>>18); 1929 divisor = clockSource/(16*rate) - 1; 1930 /* divisor has only 12 bits of resolution */ 1931 if(divisor>0x00000FFF){ 1932 divisor=0x00000FFF; 1933 } 1934 1935 quot = divisor; 1936 } 1937 1938 writeb((quot & 0x00000F00)>>8, port->uart_base + BL_SICC_BRDH ); 1939 writeb( quot & 0x00000FF, port->uart_base + BL_SICC_BRDL ); 1940 1941 /* Set CTL2 reg to use external clock (ExtClk) and enable FIFOs. */ 1942 /* For now, do NOT use FIFOs since 403 UART did not have this */ 1943 /* capability and this driver was inherited from 403UART. */ 1944 writeb(_CTL2_EXTERN, port->uart_base + BL_SICC_CTL2); 1945 1946 writeb(lcr_h, port->uart_base + BL_SICC_LCR); 1947 writeb(_RCR_ER_ENABLE | _RCR_PME_HARD, port->uart_base + BL_SICC_RCR); 1948 writeb( _TxCR_ET_ENABLE , port->uart_base + BL_SICC_TxCR); 1949 1950 // writeb(, info->port->uart_base + BL_SICC_RCR ); 1951 /* 1952 * Transmitter Command Register: Transmitter enabled & DMA + TBR interrupt 1953 * + Transmitter Empty interrupt + Transmitter error interrupt disabled & 1954 * Stop mode when CTS active enabled & Transmit Break + Pattern Generation 1955 * mode disabled. 1956 */ 1957 1958 writeb( 0x00, port->uart_base + BL_SICC_IrCR ); // disable IrDA 1959 1960 readb(port->uart_base + BL_SICC_RBR); 1961 1962 writeb(0xf8, port->uart_base + BL_SICC_LSR); /* reset bits 0-4 of LSR */ 1963 1964 /* we will enable the port as we need it */ 1965 1966 return 0; 1967} 1968 1969static struct console siccuart_cons = 1970{ 1971 .name = SERIAL_SICC_NAME, 1972 .write = siccuart_console_write, 1973#ifdef used_and_not_const_char_pointer 1974 .read = siccuart_console_read, 1975#endif 1976 .device = siccuart_console_device, 1977 .wait_key = siccuart_console_wait_key, 1978 .setup = siccuart_console_setup, 1979 .flags = CON_PRINTBUFFER, 1980 .index = -1, 1981}; 1982 1983void __init sicc_console_init(void) 1984{ 1985 register_console(&siccuart_cons); 1986} 1987 1988#endif /* CONFIG_SERIAL_SICC_CONSOLE */ 1989