Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.14 1220 lines 29 kB view raw
1/* 2 * linux/drivers/serial/cpm_uart.c 3 * 4 * Driver for CPM (SCC/SMC) serial ports; core driver 5 * 6 * Based on arch/ppc/cpm2_io/uart.c by Dan Malek 7 * Based on ppc8xx.c by Thomas Gleixner 8 * Based on drivers/serial/amba.c by Russell King 9 * 10 * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) 11 * Pantelis Antoniou (panto@intracom.gr) (CPM1) 12 * 13 * Copyright (C) 2004 Freescale Semiconductor, Inc. 14 * (C) 2004 Intracom, S.A. 15 * (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com> 16 * 17 * This program is free software; you can redistribute it and/or modify 18 * it under the terms of the GNU General Public License as published by 19 * the Free Software Foundation; either version 2 of the License, or 20 * (at your option) any later version. 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30 * 31 */ 32 33#include <linux/config.h> 34#include <linux/module.h> 35#include <linux/tty.h> 36#include <linux/ioport.h> 37#include <linux/init.h> 38#include <linux/serial.h> 39#include <linux/console.h> 40#include <linux/sysrq.h> 41#include <linux/device.h> 42#include <linux/bootmem.h> 43#include <linux/dma-mapping.h> 44 45#include <asm/io.h> 46#include <asm/irq.h> 47#include <asm/delay.h> 48 49#if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 50#define SUPPORT_SYSRQ 51#endif 52 53#include <linux/serial_core.h> 54#include <linux/kernel.h> 55 56#include "cpm_uart.h" 57 58/***********************************************************************/ 59 60/* Track which ports are configured as uarts */ 61int cpm_uart_port_map[UART_NR]; 62/* How many ports did we config as uarts */ 63int cpm_uart_nr; 64 65/**************************************************************/ 66 67static int cpm_uart_tx_pump(struct uart_port *port); 68static void cpm_uart_init_smc(struct uart_cpm_port *pinfo); 69static void cpm_uart_init_scc(struct uart_cpm_port *pinfo); 70static void cpm_uart_initbd(struct uart_cpm_port *pinfo); 71 72/**************************************************************/ 73 74static inline unsigned long cpu2cpm_addr(void *addr) 75{ 76 if ((unsigned long)addr >= CPM_ADDR) 77 return (unsigned long)addr; 78 return virt_to_bus(addr); 79} 80 81static inline void *cpm2cpu_addr(unsigned long addr) 82{ 83 if (addr >= CPM_ADDR) 84 return (void *)addr; 85 return bus_to_virt(addr); 86} 87 88/* 89 * Check, if transmit buffers are processed 90*/ 91static unsigned int cpm_uart_tx_empty(struct uart_port *port) 92{ 93 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 94 volatile cbd_t *bdp = pinfo->tx_bd_base; 95 int ret = 0; 96 97 while (1) { 98 if (bdp->cbd_sc & BD_SC_READY) 99 break; 100 101 if (bdp->cbd_sc & BD_SC_WRAP) { 102 ret = TIOCSER_TEMT; 103 break; 104 } 105 bdp++; 106 } 107 108 pr_debug("CPM uart[%d]:tx_empty: %d\n", port->line, ret); 109 110 return ret; 111} 112 113static void cpm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 114{ 115 /* Whee. Do nothing. */ 116} 117 118static unsigned int cpm_uart_get_mctrl(struct uart_port *port) 119{ 120 /* Whee. Do nothing. */ 121 return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; 122} 123 124/* 125 * Stop transmitter 126 */ 127static void cpm_uart_stop_tx(struct uart_port *port) 128{ 129 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 130 volatile smc_t *smcp = pinfo->smcp; 131 volatile scc_t *sccp = pinfo->sccp; 132 133 pr_debug("CPM uart[%d]:stop tx\n", port->line); 134 135 if (IS_SMC(pinfo)) 136 smcp->smc_smcm &= ~SMCM_TX; 137 else 138 sccp->scc_sccm &= ~UART_SCCM_TX; 139} 140 141/* 142 * Start transmitter 143 */ 144static void cpm_uart_start_tx(struct uart_port *port) 145{ 146 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 147 volatile smc_t *smcp = pinfo->smcp; 148 volatile scc_t *sccp = pinfo->sccp; 149 150 pr_debug("CPM uart[%d]:start tx\n", port->line); 151 152 if (IS_SMC(pinfo)) { 153 if (smcp->smc_smcm & SMCM_TX) 154 return; 155 } else { 156 if (sccp->scc_sccm & UART_SCCM_TX) 157 return; 158 } 159 160 if (cpm_uart_tx_pump(port) != 0) { 161 if (IS_SMC(pinfo)) { 162 smcp->smc_smcm |= SMCM_TX; 163 smcp->smc_smcmr |= SMCMR_TEN; 164 } else { 165 sccp->scc_sccm |= UART_SCCM_TX; 166 pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT; 167 } 168 } 169} 170 171/* 172 * Stop receiver 173 */ 174static void cpm_uart_stop_rx(struct uart_port *port) 175{ 176 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 177 volatile smc_t *smcp = pinfo->smcp; 178 volatile scc_t *sccp = pinfo->sccp; 179 180 pr_debug("CPM uart[%d]:stop rx\n", port->line); 181 182 if (IS_SMC(pinfo)) 183 smcp->smc_smcm &= ~SMCM_RX; 184 else 185 sccp->scc_sccm &= ~UART_SCCM_RX; 186} 187 188/* 189 * Enable Modem status interrupts 190 */ 191static void cpm_uart_enable_ms(struct uart_port *port) 192{ 193 pr_debug("CPM uart[%d]:enable ms\n", port->line); 194} 195 196/* 197 * Generate a break. 198 */ 199static void cpm_uart_break_ctl(struct uart_port *port, int break_state) 200{ 201 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 202 int line = pinfo - cpm_uart_ports; 203 204 pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, 205 break_state); 206 207 if (break_state) 208 cpm_line_cr_cmd(line, CPM_CR_STOP_TX); 209 else 210 cpm_line_cr_cmd(line, CPM_CR_RESTART_TX); 211} 212 213/* 214 * Transmit characters, refill buffer descriptor, if possible 215 */ 216static void cpm_uart_int_tx(struct uart_port *port, struct pt_regs *regs) 217{ 218 pr_debug("CPM uart[%d]:TX INT\n", port->line); 219 220 cpm_uart_tx_pump(port); 221} 222 223/* 224 * Receive characters 225 */ 226static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) 227{ 228 int i; 229 unsigned char ch, *cp; 230 struct tty_struct *tty = port->info->tty; 231 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 232 volatile cbd_t *bdp; 233 u16 status; 234 unsigned int flg; 235 236 pr_debug("CPM uart[%d]:RX INT\n", port->line); 237 238 /* Just loop through the closed BDs and copy the characters into 239 * the buffer. 240 */ 241 bdp = pinfo->rx_cur; 242 for (;;) { 243 /* get status */ 244 status = bdp->cbd_sc; 245 /* If this one is empty, return happy */ 246 if (status & BD_SC_EMPTY) 247 break; 248 249 /* get number of characters, and check spce in flip-buffer */ 250 i = bdp->cbd_datlen; 251 252 /* If we have not enough room in tty flip buffer, then we try 253 * later, which will be the next rx-interrupt or a timeout 254 */ 255 if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { 256 tty->flip.work.func((void *)tty); 257 if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { 258 printk(KERN_WARNING "TTY_DONT_FLIP set\n"); 259 return; 260 } 261 } 262 263 /* get pointer */ 264 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 265 266 /* loop through the buffer */ 267 while (i-- > 0) { 268 ch = *cp++; 269 port->icount.rx++; 270 flg = TTY_NORMAL; 271 272 if (status & 273 (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) 274 goto handle_error; 275 if (uart_handle_sysrq_char(port, ch, regs)) 276 continue; 277 278 error_return: 279 *tty->flip.char_buf_ptr++ = ch; 280 *tty->flip.flag_buf_ptr++ = flg; 281 tty->flip.count++; 282 283 } /* End while (i--) */ 284 285 /* This BD is ready to be used again. Clear status. get next */ 286 bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID); 287 bdp->cbd_sc |= BD_SC_EMPTY; 288 289 if (bdp->cbd_sc & BD_SC_WRAP) 290 bdp = pinfo->rx_bd_base; 291 else 292 bdp++; 293 294 } /* End for (;;) */ 295 296 /* Write back buffer pointer */ 297 pinfo->rx_cur = (volatile cbd_t *) bdp; 298 299 /* activate BH processing */ 300 tty_flip_buffer_push(tty); 301 302 return; 303 304 /* Error processing */ 305 306 handle_error: 307 /* Statistics */ 308 if (status & BD_SC_BR) 309 port->icount.brk++; 310 if (status & BD_SC_PR) 311 port->icount.parity++; 312 if (status & BD_SC_FR) 313 port->icount.frame++; 314 if (status & BD_SC_OV) 315 port->icount.overrun++; 316 317 /* Mask out ignored conditions */ 318 status &= port->read_status_mask; 319 320 /* Handle the remaining ones */ 321 if (status & BD_SC_BR) 322 flg = TTY_BREAK; 323 else if (status & BD_SC_PR) 324 flg = TTY_PARITY; 325 else if (status & BD_SC_FR) 326 flg = TTY_FRAME; 327 328 /* overrun does not affect the current character ! */ 329 if (status & BD_SC_OV) { 330 ch = 0; 331 flg = TTY_OVERRUN; 332 /* We skip this buffer */ 333 /* CHECK: Is really nothing senseful there */ 334 /* ASSUMPTION: it contains nothing valid */ 335 i = 0; 336 } 337#ifdef SUPPORT_SYSRQ 338 port->sysrq = 0; 339#endif 340 goto error_return; 341} 342 343/* 344 * Asynchron mode interrupt handler 345 */ 346static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs) 347{ 348 u8 events; 349 struct uart_port *port = (struct uart_port *)data; 350 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 351 volatile smc_t *smcp = pinfo->smcp; 352 volatile scc_t *sccp = pinfo->sccp; 353 354 pr_debug("CPM uart[%d]:IRQ\n", port->line); 355 356 if (IS_SMC(pinfo)) { 357 events = smcp->smc_smce; 358 smcp->smc_smce = events; 359 if (events & SMCM_BRKE) 360 uart_handle_break(port); 361 if (events & SMCM_RX) 362 cpm_uart_int_rx(port, regs); 363 if (events & SMCM_TX) 364 cpm_uart_int_tx(port, regs); 365 } else { 366 events = sccp->scc_scce; 367 sccp->scc_scce = events; 368 if (events & UART_SCCM_BRKE) 369 uart_handle_break(port); 370 if (events & UART_SCCM_RX) 371 cpm_uart_int_rx(port, regs); 372 if (events & UART_SCCM_TX) 373 cpm_uart_int_tx(port, regs); 374 } 375 return (events) ? IRQ_HANDLED : IRQ_NONE; 376} 377 378static int cpm_uart_startup(struct uart_port *port) 379{ 380 int retval; 381 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 382 int line = pinfo - cpm_uart_ports; 383 384 pr_debug("CPM uart[%d]:startup\n", port->line); 385 386 /* Install interrupt handler. */ 387 retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); 388 if (retval) 389 return retval; 390 391 /* Startup rx-int */ 392 if (IS_SMC(pinfo)) { 393 pinfo->smcp->smc_smcm |= SMCM_RX; 394 pinfo->smcp->smc_smcmr |= SMCMR_REN; 395 } else { 396 pinfo->sccp->scc_sccm |= UART_SCCM_RX; 397 } 398 399 if (!(pinfo->flags & FLAG_CONSOLE)) 400 cpm_line_cr_cmd(line,CPM_CR_INIT_TRX); 401 return 0; 402} 403 404inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo) 405{ 406 set_current_state(TASK_UNINTERRUPTIBLE); 407 schedule_timeout(pinfo->wait_closing); 408} 409 410/* 411 * Shutdown the uart 412 */ 413static void cpm_uart_shutdown(struct uart_port *port) 414{ 415 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 416 int line = pinfo - cpm_uart_ports; 417 418 pr_debug("CPM uart[%d]:shutdown\n", port->line); 419 420 /* free interrupt handler */ 421 free_irq(port->irq, port); 422 423 /* If the port is not the console, disable Rx and Tx. */ 424 if (!(pinfo->flags & FLAG_CONSOLE)) { 425 /* Wait for all the BDs marked sent */ 426 while(!cpm_uart_tx_empty(port)) { 427 set_current_state(TASK_UNINTERRUPTIBLE); 428 schedule_timeout(2); 429 } 430 431 if (pinfo->wait_closing) 432 cpm_uart_wait_until_send(pinfo); 433 434 /* Stop uarts */ 435 if (IS_SMC(pinfo)) { 436 volatile smc_t *smcp = pinfo->smcp; 437 smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 438 smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 439 } else { 440 volatile scc_t *sccp = pinfo->sccp; 441 sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); 442 sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); 443 } 444 445 /* Shut them really down and reinit buffer descriptors */ 446 cpm_line_cr_cmd(line, CPM_CR_STOP_TX); 447 cpm_uart_initbd(pinfo); 448 } 449} 450 451static void cpm_uart_set_termios(struct uart_port *port, 452 struct termios *termios, struct termios *old) 453{ 454 int baud; 455 unsigned long flags; 456 u16 cval, scval, prev_mode; 457 int bits, sbits; 458 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 459 volatile smc_t *smcp = pinfo->smcp; 460 volatile scc_t *sccp = pinfo->sccp; 461 462 pr_debug("CPM uart[%d]:set_termios\n", port->line); 463 464 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); 465 466 /* Character length programmed into the mode register is the 467 * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, 468 * 1 or 2 stop bits, minus 1. 469 * The value 'bits' counts this for us. 470 */ 471 cval = 0; 472 scval = 0; 473 474 /* byte size */ 475 switch (termios->c_cflag & CSIZE) { 476 case CS5: 477 bits = 5; 478 break; 479 case CS6: 480 bits = 6; 481 break; 482 case CS7: 483 bits = 7; 484 break; 485 case CS8: 486 bits = 8; 487 break; 488 /* Never happens, but GCC is too dumb to figure it out */ 489 default: 490 bits = 8; 491 break; 492 } 493 sbits = bits - 5; 494 495 if (termios->c_cflag & CSTOPB) { 496 cval |= SMCMR_SL; /* Two stops */ 497 scval |= SCU_PSMR_SL; 498 bits++; 499 } 500 501 if (termios->c_cflag & PARENB) { 502 cval |= SMCMR_PEN; 503 scval |= SCU_PSMR_PEN; 504 bits++; 505 if (!(termios->c_cflag & PARODD)) { 506 cval |= SMCMR_PM_EVEN; 507 scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP); 508 } 509 } 510 511 /* 512 * Set up parity check flag 513 */ 514#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) 515 516 port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); 517 if (termios->c_iflag & INPCK) 518 port->read_status_mask |= BD_SC_FR | BD_SC_PR; 519 if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK)) 520 port->read_status_mask |= BD_SC_BR; 521 522 /* 523 * Characters to ignore 524 */ 525 port->ignore_status_mask = 0; 526 if (termios->c_iflag & IGNPAR) 527 port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; 528 if (termios->c_iflag & IGNBRK) { 529 port->ignore_status_mask |= BD_SC_BR; 530 /* 531 * If we're ignore parity and break indicators, ignore 532 * overruns too. (For real raw support). 533 */ 534 if (termios->c_iflag & IGNPAR) 535 port->ignore_status_mask |= BD_SC_OV; 536 } 537 /* 538 * !!! ignore all characters if CREAD is not set 539 */ 540 if ((termios->c_cflag & CREAD) == 0) 541 port->read_status_mask &= ~BD_SC_EMPTY; 542 543 spin_lock_irqsave(&port->lock, flags); 544 545 /* Start bit has not been added (so don't, because we would just 546 * subtract it later), and we need to add one for the number of 547 * stops bits (there is always at least one). 548 */ 549 bits++; 550 if (IS_SMC(pinfo)) { 551 /* Set the mode register. We want to keep a copy of the 552 * enables, because we want to put them back if they were 553 * present. 554 */ 555 prev_mode = smcp->smc_smcmr; 556 smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; 557 smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); 558 } else { 559 sccp->scc_psmr = (sbits << 12) | scval; 560 } 561 562 cpm_set_brg(pinfo->brg - 1, baud); 563 spin_unlock_irqrestore(&port->lock, flags); 564 565} 566 567static const char *cpm_uart_type(struct uart_port *port) 568{ 569 pr_debug("CPM uart[%d]:uart_type\n", port->line); 570 571 return port->type == PORT_CPM ? "CPM UART" : NULL; 572} 573 574/* 575 * verify the new serial_struct (for TIOCSSERIAL). 576 */ 577static int cpm_uart_verify_port(struct uart_port *port, 578 struct serial_struct *ser) 579{ 580 int ret = 0; 581 582 pr_debug("CPM uart[%d]:verify_port\n", port->line); 583 584 if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) 585 ret = -EINVAL; 586 if (ser->irq < 0 || ser->irq >= NR_IRQS) 587 ret = -EINVAL; 588 if (ser->baud_base < 9600) 589 ret = -EINVAL; 590 return ret; 591} 592 593/* 594 * Transmit characters, refill buffer descriptor, if possible 595 */ 596static int cpm_uart_tx_pump(struct uart_port *port) 597{ 598 volatile cbd_t *bdp; 599 unsigned char *p; 600 int count; 601 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 602 struct circ_buf *xmit = &port->info->xmit; 603 604 /* Handle xon/xoff */ 605 if (port->x_char) { 606 /* Pick next descriptor and fill from buffer */ 607 bdp = pinfo->tx_cur; 608 609 p = cpm2cpu_addr(bdp->cbd_bufaddr); 610 611 *p++ = xmit->buf[xmit->tail]; 612 bdp->cbd_datlen = 1; 613 bdp->cbd_sc |= BD_SC_READY; 614 /* Get next BD. */ 615 if (bdp->cbd_sc & BD_SC_WRAP) 616 bdp = pinfo->tx_bd_base; 617 else 618 bdp++; 619 pinfo->tx_cur = bdp; 620 621 port->icount.tx++; 622 port->x_char = 0; 623 return 1; 624 } 625 626 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 627 cpm_uart_stop_tx(port); 628 return 0; 629 } 630 631 /* Pick next descriptor and fill from buffer */ 632 bdp = pinfo->tx_cur; 633 634 while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { 635 count = 0; 636 p = cpm2cpu_addr(bdp->cbd_bufaddr); 637 while (count < pinfo->tx_fifosize) { 638 *p++ = xmit->buf[xmit->tail]; 639 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 640 port->icount.tx++; 641 count++; 642 if (xmit->head == xmit->tail) 643 break; 644 } 645 bdp->cbd_datlen = count; 646 bdp->cbd_sc |= BD_SC_READY; 647 __asm__("eieio"); 648 /* Get next BD. */ 649 if (bdp->cbd_sc & BD_SC_WRAP) 650 bdp = pinfo->tx_bd_base; 651 else 652 bdp++; 653 } 654 pinfo->tx_cur = bdp; 655 656 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 657 uart_write_wakeup(port); 658 659 if (uart_circ_empty(xmit)) { 660 cpm_uart_stop_tx(port); 661 return 0; 662 } 663 664 return 1; 665} 666 667/* 668 * init buffer descriptors 669 */ 670static void cpm_uart_initbd(struct uart_cpm_port *pinfo) 671{ 672 int i; 673 u8 *mem_addr; 674 volatile cbd_t *bdp; 675 676 pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line); 677 678 /* Set the physical address of the host memory 679 * buffers in the buffer descriptors, and the 680 * virtual address for us to work with. 681 */ 682 mem_addr = pinfo->mem_addr; 683 bdp = pinfo->rx_cur = pinfo->rx_bd_base; 684 for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { 685 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 686 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; 687 mem_addr += pinfo->rx_fifosize; 688 } 689 690 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 691 bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; 692 693 /* Set the physical address of the host memory 694 * buffers in the buffer descriptors, and the 695 * virtual address for us to work with. 696 */ 697 mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); 698 bdp = pinfo->tx_cur = pinfo->tx_bd_base; 699 for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { 700 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 701 bdp->cbd_sc = BD_SC_INTRPT; 702 mem_addr += pinfo->tx_fifosize; 703 } 704 705 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 706 bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; 707} 708 709static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) 710{ 711 int line = pinfo - cpm_uart_ports; 712 volatile scc_t *scp; 713 volatile scc_uart_t *sup; 714 715 pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line); 716 717 scp = pinfo->sccp; 718 sup = pinfo->sccup; 719 720 /* Store address */ 721 pinfo->sccup->scc_genscc.scc_rbase = (unsigned char *)pinfo->rx_bd_base - DPRAM_BASE; 722 pinfo->sccup->scc_genscc.scc_tbase = (unsigned char *)pinfo->tx_bd_base - DPRAM_BASE; 723 724 /* Set up the uart parameters in the 725 * parameter ram. 726 */ 727 728 cpm_set_scc_fcr(sup); 729 730 sup->scc_genscc.scc_mrblr = pinfo->rx_fifosize; 731 sup->scc_maxidl = pinfo->rx_fifosize; 732 sup->scc_brkcr = 1; 733 sup->scc_parec = 0; 734 sup->scc_frmec = 0; 735 sup->scc_nosec = 0; 736 sup->scc_brkec = 0; 737 sup->scc_uaddr1 = 0; 738 sup->scc_uaddr2 = 0; 739 sup->scc_toseq = 0; 740 sup->scc_char1 = 0x8000; 741 sup->scc_char2 = 0x8000; 742 sup->scc_char3 = 0x8000; 743 sup->scc_char4 = 0x8000; 744 sup->scc_char5 = 0x8000; 745 sup->scc_char6 = 0x8000; 746 sup->scc_char7 = 0x8000; 747 sup->scc_char8 = 0x8000; 748 sup->scc_rccm = 0xc0ff; 749 750 /* Send the CPM an initialize command. 751 */ 752 cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); 753 754 /* Set UART mode, 8 bit, no parity, one stop. 755 * Enable receive and transmit. 756 */ 757 scp->scc_gsmrh = 0; 758 scp->scc_gsmrl = 759 (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); 760 761 /* Enable rx interrupts and clear all pending events. */ 762 scp->scc_sccm = 0; 763 scp->scc_scce = 0xffff; 764 scp->scc_dsr = 0x7e7e; 765 scp->scc_psmr = 0x3000; 766 767 scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); 768} 769 770static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) 771{ 772 int line = pinfo - cpm_uart_ports; 773 volatile smc_t *sp; 774 volatile smc_uart_t *up; 775 776 pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); 777 778 sp = pinfo->smcp; 779 up = pinfo->smcup; 780 781 /* Store address */ 782 pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE; 783 pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE; 784 785/* 786 * In case SMC1 is being relocated... 787 */ 788#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) 789 up->smc_rbptr = pinfo->smcup->smc_rbase; 790 up->smc_tbptr = pinfo->smcup->smc_tbase; 791 up->smc_rstate = 0; 792 up->smc_tstate = 0; 793 up->smc_brkcr = 1; /* number of break chars */ 794 up->smc_brkec = 0; 795#endif 796 797 /* Set up the uart parameters in the 798 * parameter ram. 799 */ 800 cpm_set_smc_fcr(up); 801 802 /* Using idle charater time requires some additional tuning. */ 803 up->smc_mrblr = pinfo->rx_fifosize; 804 up->smc_maxidl = pinfo->rx_fifosize; 805 up->smc_brklen = 0; 806 up->smc_brkec = 0; 807 up->smc_brkcr = 1; 808 809 cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); 810 811 /* Set UART mode, 8 bit, no parity, one stop. 812 * Enable receive and transmit. 813 */ 814 sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; 815 816 /* Enable only rx interrupts clear all pending events. */ 817 sp->smc_smcm = 0; 818 sp->smc_smce = 0xff; 819 820 sp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); 821} 822 823/* 824 * Initialize port. This is called from early_console stuff 825 * so we have to be careful here ! 826 */ 827static int cpm_uart_request_port(struct uart_port *port) 828{ 829 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 830 int ret; 831 832 pr_debug("CPM uart[%d]:request port\n", port->line); 833 834 if (pinfo->flags & FLAG_CONSOLE) 835 return 0; 836 837 /* 838 * Setup any port IO, connect any baud rate generators, 839 * etc. This is expected to be handled by board 840 * dependant code 841 */ 842 if (pinfo->set_lineif) 843 pinfo->set_lineif(pinfo); 844 845 if (IS_SMC(pinfo)) { 846 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 847 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 848 } else { 849 pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); 850 pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); 851 } 852 853 ret = cpm_uart_allocbuf(pinfo, 0); 854 855 if (ret) 856 return ret; 857 858 cpm_uart_initbd(pinfo); 859 if (IS_SMC(pinfo)) 860 cpm_uart_init_smc(pinfo); 861 else 862 cpm_uart_init_scc(pinfo); 863 864 return 0; 865} 866 867static void cpm_uart_release_port(struct uart_port *port) 868{ 869 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; 870 871 if (!(pinfo->flags & FLAG_CONSOLE)) 872 cpm_uart_freebuf(pinfo); 873} 874 875/* 876 * Configure/autoconfigure the port. 877 */ 878static void cpm_uart_config_port(struct uart_port *port, int flags) 879{ 880 pr_debug("CPM uart[%d]:config_port\n", port->line); 881 882 if (flags & UART_CONFIG_TYPE) { 883 port->type = PORT_CPM; 884 cpm_uart_request_port(port); 885 } 886} 887static struct uart_ops cpm_uart_pops = { 888 .tx_empty = cpm_uart_tx_empty, 889 .set_mctrl = cpm_uart_set_mctrl, 890 .get_mctrl = cpm_uart_get_mctrl, 891 .stop_tx = cpm_uart_stop_tx, 892 .start_tx = cpm_uart_start_tx, 893 .stop_rx = cpm_uart_stop_rx, 894 .enable_ms = cpm_uart_enable_ms, 895 .break_ctl = cpm_uart_break_ctl, 896 .startup = cpm_uart_startup, 897 .shutdown = cpm_uart_shutdown, 898 .set_termios = cpm_uart_set_termios, 899 .type = cpm_uart_type, 900 .release_port = cpm_uart_release_port, 901 .request_port = cpm_uart_request_port, 902 .config_port = cpm_uart_config_port, 903 .verify_port = cpm_uart_verify_port, 904}; 905 906struct uart_cpm_port cpm_uart_ports[UART_NR] = { 907 [UART_SMC1] = { 908 .port = { 909 .irq = SMC1_IRQ, 910 .ops = &cpm_uart_pops, 911 .iotype = SERIAL_IO_MEM, 912 .lock = SPIN_LOCK_UNLOCKED, 913 }, 914 .flags = FLAG_SMC, 915 .tx_nrfifos = TX_NUM_FIFO, 916 .tx_fifosize = TX_BUF_SIZE, 917 .rx_nrfifos = RX_NUM_FIFO, 918 .rx_fifosize = RX_BUF_SIZE, 919 .set_lineif = smc1_lineif, 920 }, 921 [UART_SMC2] = { 922 .port = { 923 .irq = SMC2_IRQ, 924 .ops = &cpm_uart_pops, 925 .iotype = SERIAL_IO_MEM, 926 .lock = SPIN_LOCK_UNLOCKED, 927 }, 928 .flags = FLAG_SMC, 929 .tx_nrfifos = TX_NUM_FIFO, 930 .tx_fifosize = TX_BUF_SIZE, 931 .rx_nrfifos = RX_NUM_FIFO, 932 .rx_fifosize = RX_BUF_SIZE, 933 .set_lineif = smc2_lineif, 934#ifdef CONFIG_SERIAL_CPM_ALT_SMC2 935 .is_portb = 1, 936#endif 937 }, 938 [UART_SCC1] = { 939 .port = { 940 .irq = SCC1_IRQ, 941 .ops = &cpm_uart_pops, 942 .iotype = SERIAL_IO_MEM, 943 .lock = SPIN_LOCK_UNLOCKED, 944 }, 945 .tx_nrfifos = TX_NUM_FIFO, 946 .tx_fifosize = TX_BUF_SIZE, 947 .rx_nrfifos = RX_NUM_FIFO, 948 .rx_fifosize = RX_BUF_SIZE, 949 .set_lineif = scc1_lineif, 950 .wait_closing = SCC_WAIT_CLOSING, 951 }, 952 [UART_SCC2] = { 953 .port = { 954 .irq = SCC2_IRQ, 955 .ops = &cpm_uart_pops, 956 .iotype = SERIAL_IO_MEM, 957 .lock = SPIN_LOCK_UNLOCKED, 958 }, 959 .tx_nrfifos = TX_NUM_FIFO, 960 .tx_fifosize = TX_BUF_SIZE, 961 .rx_nrfifos = RX_NUM_FIFO, 962 .rx_fifosize = RX_BUF_SIZE, 963 .set_lineif = scc2_lineif, 964 .wait_closing = SCC_WAIT_CLOSING, 965 }, 966 [UART_SCC3] = { 967 .port = { 968 .irq = SCC3_IRQ, 969 .ops = &cpm_uart_pops, 970 .iotype = SERIAL_IO_MEM, 971 .lock = SPIN_LOCK_UNLOCKED, 972 }, 973 .tx_nrfifos = TX_NUM_FIFO, 974 .tx_fifosize = TX_BUF_SIZE, 975 .rx_nrfifos = RX_NUM_FIFO, 976 .rx_fifosize = RX_BUF_SIZE, 977 .set_lineif = scc3_lineif, 978 .wait_closing = SCC_WAIT_CLOSING, 979 }, 980 [UART_SCC4] = { 981 .port = { 982 .irq = SCC4_IRQ, 983 .ops = &cpm_uart_pops, 984 .iotype = SERIAL_IO_MEM, 985 .lock = SPIN_LOCK_UNLOCKED, 986 }, 987 .tx_nrfifos = TX_NUM_FIFO, 988 .tx_fifosize = TX_BUF_SIZE, 989 .rx_nrfifos = RX_NUM_FIFO, 990 .rx_fifosize = RX_BUF_SIZE, 991 .set_lineif = scc4_lineif, 992 .wait_closing = SCC_WAIT_CLOSING, 993 }, 994}; 995 996#ifdef CONFIG_SERIAL_CPM_CONSOLE 997/* 998 * Print a string to the serial port trying not to disturb 999 * any possible real use of the port... 1000 * 1001 * Note that this is called with interrupts already disabled 1002 */ 1003static void cpm_uart_console_write(struct console *co, const char *s, 1004 u_int count) 1005{ 1006 struct uart_cpm_port *pinfo = 1007 &cpm_uart_ports[cpm_uart_port_map[co->index]]; 1008 unsigned int i; 1009 volatile cbd_t *bdp, *bdbase; 1010 volatile unsigned char *cp; 1011 1012 /* Get the address of the host memory buffer. 1013 */ 1014 bdp = pinfo->tx_cur; 1015 bdbase = pinfo->tx_bd_base; 1016 1017 /* 1018 * Now, do each character. This is not as bad as it looks 1019 * since this is a holding FIFO and not a transmitting FIFO. 1020 * We could add the complexity of filling the entire transmit 1021 * buffer, but we would just wait longer between accesses...... 1022 */ 1023 for (i = 0; i < count; i++, s++) { 1024 /* Wait for transmitter fifo to empty. 1025 * Ready indicates output is ready, and xmt is doing 1026 * that, not that it is ready for us to send. 1027 */ 1028 while ((bdp->cbd_sc & BD_SC_READY) != 0) 1029 ; 1030 1031 /* Send the character out. 1032 * If the buffer address is in the CPM DPRAM, don't 1033 * convert it. 1034 */ 1035 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 1036 1037 *cp = *s; 1038 1039 bdp->cbd_datlen = 1; 1040 bdp->cbd_sc |= BD_SC_READY; 1041 1042 if (bdp->cbd_sc & BD_SC_WRAP) 1043 bdp = bdbase; 1044 else 1045 bdp++; 1046 1047 /* if a LF, also do CR... */ 1048 if (*s == 10) { 1049 while ((bdp->cbd_sc & BD_SC_READY) != 0) 1050 ; 1051 1052 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 1053 1054 *cp = 13; 1055 bdp->cbd_datlen = 1; 1056 bdp->cbd_sc |= BD_SC_READY; 1057 1058 if (bdp->cbd_sc & BD_SC_WRAP) 1059 bdp = bdbase; 1060 else 1061 bdp++; 1062 } 1063 } 1064 1065 /* 1066 * Finally, Wait for transmitter & holding register to empty 1067 * and restore the IER 1068 */ 1069 while ((bdp->cbd_sc & BD_SC_READY) != 0) 1070 ; 1071 1072 pinfo->tx_cur = (volatile cbd_t *) bdp; 1073} 1074 1075/* 1076 * Setup console. Be careful is called early ! 1077 */ 1078static int __init cpm_uart_console_setup(struct console *co, char *options) 1079{ 1080 struct uart_port *port; 1081 struct uart_cpm_port *pinfo; 1082 int baud = 38400; 1083 int bits = 8; 1084 int parity = 'n'; 1085 int flow = 'n'; 1086 int ret; 1087 1088 port = 1089 (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; 1090 pinfo = (struct uart_cpm_port *)port; 1091 1092 pinfo->flags |= FLAG_CONSOLE; 1093 1094 if (options) { 1095 uart_parse_options(options, &baud, &parity, &bits, &flow); 1096 } else { 1097 bd_t *bd = (bd_t *) __res; 1098 1099 if (bd->bi_baudrate) 1100 baud = bd->bi_baudrate; 1101 else 1102 baud = 9600; 1103 } 1104 1105 /* 1106 * Setup any port IO, connect any baud rate generators, 1107 * etc. This is expected to be handled by board 1108 * dependant code 1109 */ 1110 if (pinfo->set_lineif) 1111 pinfo->set_lineif(pinfo); 1112 1113 if (IS_SMC(pinfo)) { 1114 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 1115 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 1116 } else { 1117 pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); 1118 pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); 1119 } 1120 1121 ret = cpm_uart_allocbuf(pinfo, 1); 1122 1123 if (ret) 1124 return ret; 1125 1126 cpm_uart_initbd(pinfo); 1127 1128 if (IS_SMC(pinfo)) 1129 cpm_uart_init_smc(pinfo); 1130 else 1131 cpm_uart_init_scc(pinfo); 1132 1133 uart_set_options(port, co, baud, parity, bits, flow); 1134 1135 return 0; 1136} 1137 1138static struct uart_driver cpm_reg; 1139static struct console cpm_scc_uart_console = { 1140 .name = "ttyCPM", 1141 .write = cpm_uart_console_write, 1142 .device = uart_console_device, 1143 .setup = cpm_uart_console_setup, 1144 .flags = CON_PRINTBUFFER, 1145 .index = -1, 1146 .data = &cpm_reg, 1147}; 1148 1149int __init cpm_uart_console_init(void) 1150{ 1151 int ret = cpm_uart_init_portdesc(); 1152 1153 if (!ret) 1154 register_console(&cpm_scc_uart_console); 1155 return ret; 1156} 1157 1158console_initcall(cpm_uart_console_init); 1159 1160#define CPM_UART_CONSOLE &cpm_scc_uart_console 1161#else 1162#define CPM_UART_CONSOLE NULL 1163#endif 1164 1165static struct uart_driver cpm_reg = { 1166 .owner = THIS_MODULE, 1167 .driver_name = "ttyCPM", 1168 .dev_name = "ttyCPM", 1169 .major = SERIAL_CPM_MAJOR, 1170 .minor = SERIAL_CPM_MINOR, 1171 .cons = CPM_UART_CONSOLE, 1172}; 1173 1174static int __init cpm_uart_init(void) 1175{ 1176 int ret, i; 1177 1178 printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n"); 1179 1180#ifndef CONFIG_SERIAL_CPM_CONSOLE 1181 ret = cpm_uart_init_portdesc(); 1182 if (ret) 1183 return ret; 1184#endif 1185 1186 cpm_reg.nr = cpm_uart_nr; 1187 ret = uart_register_driver(&cpm_reg); 1188 1189 if (ret) 1190 return ret; 1191 1192 for (i = 0; i < cpm_uart_nr; i++) { 1193 int con = cpm_uart_port_map[i]; 1194 cpm_uart_ports[con].port.line = i; 1195 cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF; 1196 uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port); 1197 } 1198 1199 return ret; 1200} 1201 1202static void __exit cpm_uart_exit(void) 1203{ 1204 int i; 1205 1206 for (i = 0; i < cpm_uart_nr; i++) { 1207 int con = cpm_uart_port_map[i]; 1208 uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port); 1209 } 1210 1211 uart_unregister_driver(&cpm_reg); 1212} 1213 1214module_init(cpm_uart_init); 1215module_exit(cpm_uart_exit); 1216 1217MODULE_AUTHOR("Kumar Gala/Antoniou Pantelis"); 1218MODULE_DESCRIPTION("CPM SCC/SMC port driver $Revision: 0.01 $"); 1219MODULE_LICENSE("GPL"); 1220MODULE_ALIAS_CHARDEV(SERIAL_CPM_MAJOR, SERIAL_CPM_MINOR);