2  * drivers/char/vme_scc.c: MVME147, MVME162, BVME6000 SCC serial ports
 
   4  * Copyright 1999 Richard Hirst <richard@sleepie.demon.co.uk>
 
   6  * Based on atari_SCC.c which was
 
   7  *   Copyright 1994-95 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
 
   8  *   Partially based on PC-Linux serial.c by Linus Torvalds and Theodore Ts'o
 
  10  * This file is subject to the terms and conditions of the GNU General Public
 
  11  * License.  See the file COPYING in the main directory of this archive
 
  16 #include <linux/module.h>
 
  17 #include <linux/kdev_t.h>
 
  19 #include <linux/kernel.h>
 
  20 #include <linux/ioport.h>
 
  21 #include <linux/interrupt.h>
 
  22 #include <linux/errno.h>
 
  23 #include <linux/tty.h>
 
  24 #include <linux/tty_flip.h>
 
  26 #include <linux/serial.h>
 
  27 #include <linux/fcntl.h>
 
  28 #include <linux/major.h>
 
  29 #include <linux/delay.h>
 
  30 #include <linux/slab.h>
 
  31 #include <linux/miscdevice.h>
 
  32 #include <linux/console.h>
 
  33 #include <linux/init.h>
 
  34 #include <asm/setup.h>
 
  35 #include <asm/bootinfo.h>
 
  37 #ifdef CONFIG_MVME147_SCC
 
  38 #include <asm/mvme147hw.h>
 
  40 #ifdef CONFIG_MVME162_SCC
 
  41 #include <asm/mvme16xhw.h>
 
  43 #ifdef CONFIG_BVME6000_SCC
 
  44 #include <asm/bvme6000hw.h>
 
  47 #include <linux/generic_serial.h>
 
  54 #define SCC_MINOR_BASE  64
 
  56 /* Shadows for all SCC write registers */
 
  57 static unsigned char scc_shadow[2][16];
 
  59 /* Location to access for SCC register access delay */
 
  60 static volatile unsigned char *scc_del = NULL;
 
  62 /* To keep track of STATUS_REG state for detection of Ext/Status int source */
 
  63 static unsigned char scc_last_status_reg[2];
 
  65 /***************************** Prototypes *****************************/
 
  67 /* Function prototypes */
 
  68 static void scc_disable_tx_interrupts(void * ptr);
 
  69 static void scc_enable_tx_interrupts(void * ptr);
 
  70 static void scc_disable_rx_interrupts(void * ptr);
 
  71 static void scc_enable_rx_interrupts(void * ptr);
 
  72 static int  scc_get_CD(void * ptr);
 
  73 static void scc_shutdown_port(void * ptr);
 
  74 static int scc_set_real_termios(void  *ptr);
 
  75 static void scc_hungup(void  *ptr);
 
  76 static void scc_close(void  *ptr);
 
  77 static int scc_chars_in_buffer(void * ptr);
 
  78 static int scc_open(struct tty_struct * tty, struct file * filp);
 
  79 static int scc_ioctl(struct tty_struct * tty, struct file * filp,
 
  80                      unsigned int cmd, unsigned long arg);
 
  81 static void scc_throttle(struct tty_struct *tty);
 
  82 static void scc_unthrottle(struct tty_struct *tty);
 
  83 static irqreturn_t scc_tx_int(int irq, void *data);
 
  84 static irqreturn_t scc_rx_int(int irq, void *data);
 
  85 static irqreturn_t scc_stat_int(int irq, void *data);
 
  86 static irqreturn_t scc_spcond_int(int irq, void *data);
 
  87 static void scc_setsignals(struct scc_port *port, int dtr, int rts);
 
  88 static void scc_break_ctl(struct tty_struct *tty, int break_state);
 
  90 static struct tty_driver *scc_driver;
 
  92 struct scc_port scc_ports[2];
 
  94 int scc_initialized = 0;
 
  96 /*---------------------------------------------------------------------------
 
  97  * Interface from generic_serial.c back here
 
  98  *--------------------------------------------------------------------------*/
 
 100 static struct real_driver scc_real_driver = {
 
 101         scc_disable_tx_interrupts,
 
 102         scc_enable_tx_interrupts,
 
 103         scc_disable_rx_interrupts,
 
 104         scc_enable_rx_interrupts,
 
 107         scc_set_real_termios,
 
 115 static const struct tty_operations scc_ops = {
 
 119         .put_char = gs_put_char,
 
 120         .flush_chars = gs_flush_chars,
 
 121         .write_room = gs_write_room,
 
 122         .chars_in_buffer = gs_chars_in_buffer,
 
 123         .flush_buffer = gs_flush_buffer,
 
 125         .throttle = scc_throttle,
 
 126         .unthrottle = scc_unthrottle,
 
 127         .set_termios = gs_set_termios,
 
 131         .break_ctl = scc_break_ctl,
 
 134 /*----------------------------------------------------------------------------
 
 135  * vme_scc_init() and support functions
 
 136  *---------------------------------------------------------------------------*/
 
 138 static int scc_init_drivers(void)
 
 142         scc_driver = alloc_tty_driver(2);
 
 145         scc_driver->owner = THIS_MODULE;
 
 146         scc_driver->driver_name = "scc";
 
 147         scc_driver->name = "ttyS";
 
 148         scc_driver->major = TTY_MAJOR;
 
 149         scc_driver->minor_start = SCC_MINOR_BASE;
 
 150         scc_driver->type = TTY_DRIVER_TYPE_SERIAL;
 
 151         scc_driver->subtype = SERIAL_TYPE_NORMAL;
 
 152         scc_driver->init_termios = tty_std_termios;
 
 153         scc_driver->init_termios.c_cflag =
 
 154           B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 
 155         scc_driver->init_termios.c_ispeed = 9600;
 
 156         scc_driver->init_termios.c_ospeed = 9600;
 
 157         scc_driver->flags = TTY_DRIVER_REAL_RAW;
 
 158         tty_set_operations(scc_driver, &scc_ops);
 
 160         if ((error = tty_register_driver(scc_driver))) {
 
 161                 printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n",
 
 163                 put_tty_driver(scc_driver);
 
 171 /* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1).
 
 174 static void scc_init_portstructs(void)
 
 176         struct scc_port *port;
 
 179         for (i = 0; i < 2; i++) {
 
 180                 port = scc_ports + i;
 
 181                 port->gs.magic = SCC_MAGIC;
 
 182                 port->gs.close_delay = HZ/2;
 
 183                 port->gs.closing_wait = 30 * HZ;
 
 184                 port->gs.rd = &scc_real_driver;
 
 185 #ifdef NEW_WRITE_LOCKING
 
 186                 port->gs.port_write_mutex = MUTEX;
 
 188                 init_waitqueue_head(&port->gs.open_wait);
 
 189                 init_waitqueue_head(&port->gs.close_wait);
 
 194 #ifdef CONFIG_MVME147_SCC
 
 195 static int mvme147_scc_init(void)
 
 197         struct scc_port *port;
 
 199         printk(KERN_INFO "SCC: MVME147 Serial Driver\n");
 
 201         port = &scc_ports[0];
 
 202         port->channel = CHANNEL_A;
 
 203         port->ctrlp = (volatile unsigned char *)M147_SCC_A_ADDR;
 
 204         port->datap = port->ctrlp + 1;
 
 205         port->port_a = &scc_ports[0];
 
 206         port->port_b = &scc_ports[1];
 
 207         request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
 
 209         request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
 
 210                             "SCC-A status", port);
 
 211         request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
 
 213         request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
 
 214                             "SCC-A special cond", port);
 
 216                 SCC_ACCESS_INIT(port);
 
 218                 /* disable interrupts for this channel */
 
 219                 SCCwrite(INT_AND_DMA_REG, 0);
 
 220                 /* Set the interrupt vector */
 
 221                 SCCwrite(INT_VECTOR_REG, MVME147_IRQ_SCC_BASE);
 
 222                 /* Interrupt parameters: vector includes status, status low */
 
 223                 SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
 
 224                 SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
 
 228         port = &scc_ports[1];
 
 229         port->channel = CHANNEL_B;
 
 230         port->ctrlp = (volatile unsigned char *)M147_SCC_B_ADDR;
 
 231         port->datap = port->ctrlp + 1;
 
 232         port->port_a = &scc_ports[0];
 
 233         port->port_b = &scc_ports[1];
 
 234         request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
 
 236         request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
 
 237                             "SCC-B status", port);
 
 238         request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
 
 240         request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
 
 241                             "SCC-B special cond", port);
 
 243                 SCC_ACCESS_INIT(port);
 
 245                 /* disable interrupts for this channel */
 
 246                 SCCwrite(INT_AND_DMA_REG, 0);
 
 249         /* Ensure interrupts are enabled in the PCC chip */
 
 250         m147_pcc->serial_cntrl=PCC_LEVEL_SERIAL|PCC_INT_ENAB;
 
 252         /* Initialise the tty driver structures and register */
 
 253         scc_init_portstructs();
 
 261 #ifdef CONFIG_MVME162_SCC
 
 262 static int mvme162_scc_init(void)
 
 264         struct scc_port *port;
 
 266         if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA))
 
 269         printk(KERN_INFO "SCC: MVME162 Serial Driver\n");
 
 271         port = &scc_ports[0];
 
 272         port->channel = CHANNEL_A;
 
 273         port->ctrlp = (volatile unsigned char *)MVME_SCC_A_ADDR;
 
 274         port->datap = port->ctrlp + 2;
 
 275         port->port_a = &scc_ports[0];
 
 276         port->port_b = &scc_ports[1];
 
 277         request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
 
 279         request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
 
 280                             "SCC-A status", port);
 
 281         request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
 
 283         request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
 
 284                             "SCC-A special cond", port);
 
 286                 SCC_ACCESS_INIT(port);
 
 288                 /* disable interrupts for this channel */
 
 289                 SCCwrite(INT_AND_DMA_REG, 0);
 
 290                 /* Set the interrupt vector */
 
 291                 SCCwrite(INT_VECTOR_REG, MVME162_IRQ_SCC_BASE);
 
 292                 /* Interrupt parameters: vector includes status, status low */
 
 293                 SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
 
 294                 SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
 
 298         port = &scc_ports[1];
 
 299         port->channel = CHANNEL_B;
 
 300         port->ctrlp = (volatile unsigned char *)MVME_SCC_B_ADDR;
 
 301         port->datap = port->ctrlp + 2;
 
 302         port->port_a = &scc_ports[0];
 
 303         port->port_b = &scc_ports[1];
 
 304         request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
 
 306         request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
 
 307                             "SCC-B status", port);
 
 308         request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
 
 310         request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
 
 311                             "SCC-B special cond", port);
 
 314                 SCC_ACCESS_INIT(port);  /* Either channel will do */
 
 316                 /* disable interrupts for this channel */
 
 317                 SCCwrite(INT_AND_DMA_REG, 0);
 
 320         /* Ensure interrupts are enabled in the MC2 chip */
 
 321         *(volatile char *)0xfff4201d = 0x14;
 
 323         /* Initialise the tty driver structures and register */
 
 324         scc_init_portstructs();
 
 332 #ifdef CONFIG_BVME6000_SCC
 
 333 static int bvme6000_scc_init(void)
 
 335         struct scc_port *port;
 
 337         printk(KERN_INFO "SCC: BVME6000 Serial Driver\n");
 
 339         port = &scc_ports[0];
 
 340         port->channel = CHANNEL_A;
 
 341         port->ctrlp = (volatile unsigned char *)BVME_SCC_A_ADDR;
 
 342         port->datap = port->ctrlp + 4;
 
 343         port->port_a = &scc_ports[0];
 
 344         port->port_b = &scc_ports[1];
 
 345         request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
 
 347         request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
 
 348                             "SCC-A status", port);
 
 349         request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
 
 351         request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
 
 352                             "SCC-A special cond", port);
 
 354                 SCC_ACCESS_INIT(port);
 
 356                 /* disable interrupts for this channel */
 
 357                 SCCwrite(INT_AND_DMA_REG, 0);
 
 358                 /* Set the interrupt vector */
 
 359                 SCCwrite(INT_VECTOR_REG, BVME_IRQ_SCC_BASE);
 
 360                 /* Interrupt parameters: vector includes status, status low */
 
 361                 SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
 
 362                 SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
 
 366         port = &scc_ports[1];
 
 367         port->channel = CHANNEL_B;
 
 368         port->ctrlp = (volatile unsigned char *)BVME_SCC_B_ADDR;
 
 369         port->datap = port->ctrlp + 4;
 
 370         port->port_a = &scc_ports[0];
 
 371         port->port_b = &scc_ports[1];
 
 372         request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
 
 374         request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
 
 375                             "SCC-B status", port);
 
 376         request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
 
 378         request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
 
 379                             "SCC-B special cond", port);
 
 382                 SCC_ACCESS_INIT(port);  /* Either channel will do */
 
 384                 /* disable interrupts for this channel */
 
 385                 SCCwrite(INT_AND_DMA_REG, 0);
 
 388         /* Initialise the tty driver structures and register */
 
 389         scc_init_portstructs();
 
 397 static int vme_scc_init(void)
 
 401 #ifdef CONFIG_MVME147_SCC
 
 403                 res = mvme147_scc_init();
 
 405 #ifdef CONFIG_MVME162_SCC
 
 407                 res = mvme162_scc_init();
 
 409 #ifdef CONFIG_BVME6000_SCC
 
 410         if (MACH_IS_BVME6000)
 
 411                 res = bvme6000_scc_init();
 
 416 module_init(vme_scc_init);
 
 419 /*---------------------------------------------------------------------------
 
 421  *--------------------------------------------------------------------------*/
 
 423 static irqreturn_t scc_rx_int(int irq, void *data)
 
 426         struct scc_port *port = data;
 
 427         struct tty_struct *tty = port->gs.tty;
 
 428         SCC_ACCESS_INIT(port);
 
 430         ch = SCCread_NB(RX_DATA_REG);
 
 432                 printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
 
 433                 SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 
 436         tty_insert_flip_char(tty, ch, 0);
 
 438         /* Check if another character is already ready; in that case, the
 
 439          * spcond_int() function must be used, because this character may have an
 
 440          * error condition that isn't signalled by the interrupt vector used!
 
 442         if (SCCread(INT_PENDING_REG) &
 
 443             (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) {
 
 444                 scc_spcond_int (irq, data);
 
 448         SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 
 450         tty_flip_buffer_push(tty);
 
 455 static irqreturn_t scc_spcond_int(int irq, void *data)
 
 457         struct scc_port *port = data;
 
 458         struct tty_struct *tty = port->gs.tty;
 
 459         unsigned char   stat, ch, err;
 
 460         int             int_pending_mask = port->channel == CHANNEL_A ?
 
 462         SCC_ACCESS_INIT(port);
 
 465                 printk(KERN_WARNING "scc_spcond_int with NULL tty!\n");
 
 466                 SCCwrite(COMMAND_REG, CR_ERROR_RESET);
 
 467                 SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 
 471                 stat = SCCread(SPCOND_STATUS_REG);
 
 472                 ch = SCCread_NB(RX_DATA_REG);
 
 474                 if (stat & SCSR_RX_OVERRUN)
 
 476                 else if (stat & SCSR_PARITY_ERR)
 
 478                 else if (stat & SCSR_CRC_FRAME_ERR)
 
 483                 tty_insert_flip_char(tty, ch, err);
 
 485                 /* ++TeSche: *All* errors have to be cleared manually,
 
 486                  * else the condition persists for the next chars
 
 489                   SCCwrite(COMMAND_REG, CR_ERROR_RESET);
 
 491         } while(SCCread(INT_PENDING_REG) & int_pending_mask);
 
 493         SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 
 495         tty_flip_buffer_push(tty);
 
 500 static irqreturn_t scc_tx_int(int irq, void *data)
 
 502         struct scc_port *port = data;
 
 503         SCC_ACCESS_INIT(port);
 
 506                 printk(KERN_WARNING "scc_tx_int with NULL tty!\n");
 
 507                 SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
 
 508                 SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
 
 509                 SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 
 512         while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) {
 
 514                         SCCwrite(TX_DATA_REG, port->x_char);
 
 517                 else if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
 
 518                                 port->gs.tty->hw_stopped)
 
 521                         SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]);
 
 522                         port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1);
 
 523                         if (--port->gs.xmit_cnt <= 0)
 
 527         if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
 
 528                         port->gs.tty->hw_stopped) {
 
 529                 /* disable tx interrupts */
 
 530                 SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
 
 531                 SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);   /* disable tx_int on next tx underrun? */
 
 532                 port->gs.flags &= ~GS_TX_INTEN;
 
 534         if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars)
 
 535                 tty_wakeup(port->gs.tty);
 
 537         SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 
 542 static irqreturn_t scc_stat_int(int irq, void *data)
 
 544         struct scc_port *port = data;
 
 545         unsigned channel = port->channel;
 
 546         unsigned char   last_sr, sr, changed;
 
 547         SCC_ACCESS_INIT(port);
 
 549         last_sr = scc_last_status_reg[channel];
 
 550         sr = scc_last_status_reg[channel] = SCCread_NB(STATUS_REG);
 
 551         changed = last_sr ^ sr;
 
 553         if (changed & SR_DCD) {
 
 554                 port->c_dcd = !!(sr & SR_DCD);
 
 555                 if (!(port->gs.flags & ASYNC_CHECK_CD))
 
 556                         ;       /* Don't report DCD changes */
 
 557                 else if (port->c_dcd) {
 
 558                         wake_up_interruptible(&port->gs.open_wait);
 
 562                                 tty_hangup (port->gs.tty);
 
 565         SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET);
 
 566         SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 
 571 /*---------------------------------------------------------------------------
 
 572  * generic_serial.c callback funtions
 
 573  *--------------------------------------------------------------------------*/
 
 575 static void scc_disable_tx_interrupts(void *ptr)
 
 577         struct scc_port *port = ptr;
 
 579         SCC_ACCESS_INIT(port);
 
 581         local_irq_save(flags);
 
 582         SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
 
 583         port->gs.flags &= ~GS_TX_INTEN;
 
 584         local_irq_restore(flags);
 
 588 static void scc_enable_tx_interrupts(void *ptr)
 
 590         struct scc_port *port = ptr;
 
 592         SCC_ACCESS_INIT(port);
 
 594         local_irq_save(flags);
 
 595         SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB);
 
 596         /* restart the transmitter */
 
 597         scc_tx_int (0, port);
 
 598         local_irq_restore(flags);
 
 602 static void scc_disable_rx_interrupts(void *ptr)
 
 604         struct scc_port *port = ptr;
 
 606         SCC_ACCESS_INIT(port);
 
 608         local_irq_save(flags);
 
 609         SCCmod(INT_AND_DMA_REG,
 
 610             ~(IDR_RX_INT_MASK|IDR_PARERR_AS_SPCOND|IDR_EXTSTAT_INT_ENAB), 0);
 
 611         local_irq_restore(flags);
 
 615 static void scc_enable_rx_interrupts(void *ptr)
 
 617         struct scc_port *port = ptr;
 
 619         SCC_ACCESS_INIT(port);
 
 621         local_irq_save(flags);
 
 622         SCCmod(INT_AND_DMA_REG, 0xff,
 
 623                 IDR_EXTSTAT_INT_ENAB|IDR_PARERR_AS_SPCOND|IDR_RX_INT_ALL);
 
 624         local_irq_restore(flags);
 
 628 static int scc_get_CD(void *ptr)
 
 630         struct scc_port *port = ptr;
 
 631         unsigned channel = port->channel;
 
 633         return !!(scc_last_status_reg[channel] & SR_DCD);
 
 637 static void scc_shutdown_port(void *ptr)
 
 639         struct scc_port *port = ptr;
 
 641         port->gs.flags &= ~ GS_ACTIVE;
 
 642         if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) {
 
 643                 scc_setsignals (port, 0, 0);
 
 648 static int scc_set_real_termios (void *ptr)
 
 650         /* the SCC has char sizes 5,7,6,8 in that order! */
 
 651         static int chsize_map[4] = { 0, 2, 1, 3 };
 
 652         unsigned cflag, baud, chsize, channel, brgval = 0;
 
 654         struct scc_port *port = ptr;
 
 655         SCC_ACCESS_INIT(port);
 
 657         if (!port->gs.tty || !port->gs.tty->termios) return 0;
 
 659         channel = port->channel;
 
 661         if (channel == CHANNEL_A)
 
 662                 return 0;               /* Settings controlled by boot PROM */
 
 664         cflag  = port->gs.tty->termios->c_cflag;
 
 665         baud = port->gs.baud;
 
 666         chsize = (cflag & CSIZE) >> 4;
 
 669                 /* speed == 0 -> drop DTR */
 
 670                 local_irq_save(flags);
 
 671                 SCCmod(TX_CTRL_REG, ~TCR_DTR, 0);
 
 672                 local_irq_restore(flags);
 
 675         else if ((MACH_IS_MVME16x && (baud < 50 || baud > 38400)) ||
 
 676                  (MACH_IS_MVME147 && (baud < 50 || baud > 19200)) ||
 
 677                  (MACH_IS_BVME6000 &&(baud < 50 || baud > 76800))) {
 
 678                 printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud);
 
 683                 port->gs.flags &= ~ASYNC_CHECK_CD;
 
 685                 port->gs.flags |= ASYNC_CHECK_CD;
 
 687 #ifdef CONFIG_MVME147_SCC
 
 689                 brgval = (M147_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2;
 
 691 #ifdef CONFIG_MVME162_SCC
 
 693                 brgval = (MVME_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2;
 
 695 #ifdef CONFIG_BVME6000_SCC
 
 696         if (MACH_IS_BVME6000)
 
 697                 brgval = (BVME_SCC_RTxC + baud/2) / (16 * 2 * baud) - 2;
 
 699         /* Now we have all parameters and can go to set them: */
 
 700         local_irq_save(flags);
 
 702         /* receiver's character size and auto-enables */
 
 703         SCCmod(RX_CTRL_REG, ~(RCR_CHSIZE_MASK|RCR_AUTO_ENAB_MODE),
 
 704                         (chsize_map[chsize] << 6) |
 
 705                         ((cflag & CRTSCTS) ? RCR_AUTO_ENAB_MODE : 0));
 
 706         /* parity and stop bits (both, Tx and Rx), clock mode never changes */
 
 707         SCCmod (AUX1_CTRL_REG,
 
 708                 ~(A1CR_PARITY_MASK | A1CR_MODE_MASK),
 
 710                   ? (cflag & PARODD ? A1CR_PARITY_ODD : A1CR_PARITY_EVEN)
 
 712                  | (cflag & CSTOPB ? A1CR_MODE_ASYNC_2 : A1CR_MODE_ASYNC_1)));
 
 713         /* sender's character size, set DTR for valid baud rate */
 
 714         SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK, chsize_map[chsize] << 5 | TCR_DTR);
 
 715         /* clock sources never change */
 
 716         /* disable BRG before changing the value */
 
 717         SCCmod(DPLL_CTRL_REG, ~DCR_BRG_ENAB, 0);
 
 719         SCCwrite(TIMER_LOW_REG, brgval & 0xff);
 
 720         SCCwrite(TIMER_HIGH_REG, (brgval >> 8) & 0xff);
 
 721         /* BRG enable, and clock source never changes */
 
 722         SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB);
 
 724         local_irq_restore(flags);
 
 730 static int scc_chars_in_buffer (void *ptr)
 
 732         struct scc_port *port = ptr;
 
 733         SCC_ACCESS_INIT(port);
 
 735         return (SCCread (SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0  : 1;
 
 739 /* Comment taken from sx.c (2.4.0):
 
 740    I haven't the foggiest why the decrement use count has to happen
 
 741    here. The whole linux serial drivers stuff needs to be redesigned.
 
 742    My guess is that this is a hack to minimize the impact of a bug
 
 743    elsewhere. Thinking about it some more. (try it sometime) Try
 
 744    running minicom on a serial port that is driven by a modularized
 
 745    driver. Have the modem hangup. Then remove the driver module. Then
 
 746    exit minicom.  I expect an "oops".  -- REW */
 
 748 static void scc_hungup(void *ptr)
 
 750         scc_disable_tx_interrupts(ptr);
 
 751         scc_disable_rx_interrupts(ptr);
 
 755 static void scc_close(void *ptr)
 
 757         scc_disable_tx_interrupts(ptr);
 
 758         scc_disable_rx_interrupts(ptr);
 
 762 /*---------------------------------------------------------------------------
 
 763  * Internal support functions
 
 764  *--------------------------------------------------------------------------*/
 
 766 static void scc_setsignals(struct scc_port *port, int dtr, int rts)
 
 770         SCC_ACCESS_INIT(port);
 
 772         local_irq_save(flags);
 
 773         t = SCCread(TX_CTRL_REG);
 
 774         if (dtr >= 0) t = dtr? (t | TCR_DTR): (t & ~TCR_DTR);
 
 775         if (rts >= 0) t = rts? (t | TCR_RTS): (t & ~TCR_RTS);
 
 776         SCCwrite(TX_CTRL_REG, t);
 
 777         local_irq_restore(flags);
 
 781 static void scc_send_xchar(struct tty_struct *tty, char ch)
 
 783         struct scc_port *port = (struct scc_port *)tty->driver_data;
 
 787                 scc_enable_tx_interrupts(port);
 
 791 /*---------------------------------------------------------------------------
 
 792  * Driver entrypoints referenced from above
 
 793  *--------------------------------------------------------------------------*/
 
 795 static int scc_open (struct tty_struct * tty, struct file * filp)
 
 797         int line = tty->index;
 
 799         struct scc_port *port = &scc_ports[line];
 
 800         int i, channel = port->channel;
 
 802         SCC_ACCESS_INIT(port);
 
 803 #if defined(CONFIG_MVME162_SCC) || defined(CONFIG_MVME147_SCC)
 
 804         static const struct {
 
 806         } mvme_init_tab[] = {
 
 807                 /* Values for MVME162 and MVME147 */
 
 808                 /* no parity, 1 stop bit, async, 1:16 */
 
 809                 { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 },
 
 810                 /* parity error is special cond, ints disabled, no DMA */
 
 811                 { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB },
 
 812                 /* Rx 8 bits/char, no auto enable, Rx off */
 
 813                 { RX_CTRL_REG, RCR_CHSIZE_8 },
 
 814                 /* DTR off, Tx 8 bits/char, RTS off, Tx off */
 
 815                 { TX_CTRL_REG, TCR_CHSIZE_8 },
 
 816                 /* special features off */
 
 817                 { AUX2_CTRL_REG, 0 },
 
 818                 { CLK_CTRL_REG, CCR_RXCLK_BRG | CCR_TXCLK_BRG },
 
 819                 { DPLL_CTRL_REG, DCR_BRG_ENAB | DCR_BRG_USE_PCLK },
 
 821                 { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 },
 
 823                 { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 },
 
 824                 /* Ext/Stat ints: DCD only */
 
 825                 { INT_CTRL_REG, ICR_ENAB_DCD_INT },
 
 826                 /* Reset Ext/Stat ints */
 
 827                 { COMMAND_REG, CR_EXTSTAT_RESET },
 
 829                 { COMMAND_REG, CR_EXTSTAT_RESET },
 
 832 #if defined(CONFIG_BVME6000_SCC)
 
 833         static const struct {
 
 835         } bvme_init_tab[] = {
 
 836                 /* Values for BVME6000 */
 
 837                 /* no parity, 1 stop bit, async, 1:16 */
 
 838                 { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 },
 
 839                 /* parity error is special cond, ints disabled, no DMA */
 
 840                 { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB },
 
 841                 /* Rx 8 bits/char, no auto enable, Rx off */
 
 842                 { RX_CTRL_REG, RCR_CHSIZE_8 },
 
 843                 /* DTR off, Tx 8 bits/char, RTS off, Tx off */
 
 844                 { TX_CTRL_REG, TCR_CHSIZE_8 },
 
 845                 /* special features off */
 
 846                 { AUX2_CTRL_REG, 0 },
 
 847                 { CLK_CTRL_REG, CCR_RTxC_XTAL | CCR_RXCLK_BRG | CCR_TXCLK_BRG },
 
 848                 { DPLL_CTRL_REG, DCR_BRG_ENAB },
 
 850                 { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 },
 
 852                 { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 },
 
 853                 /* Ext/Stat ints: DCD only */
 
 854                 { INT_CTRL_REG, ICR_ENAB_DCD_INT },
 
 855                 /* Reset Ext/Stat ints */
 
 856                 { COMMAND_REG, CR_EXTSTAT_RESET },
 
 858                 { COMMAND_REG, CR_EXTSTAT_RESET },
 
 861         if (!(port->gs.flags & ASYNC_INITIALIZED)) {
 
 862                 local_irq_save(flags);
 
 863 #if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC)
 
 864                 if (MACH_IS_MVME147 || MACH_IS_MVME16x) {
 
 865                         for (i = 0; i < ARRAY_SIZE(mvme_init_tab); ++i)
 
 866                                 SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val);
 
 869 #if defined(CONFIG_BVME6000_SCC)
 
 870                 if (MACH_IS_BVME6000) {
 
 871                         for (i = 0; i < ARRAY_SIZE(bvme_init_tab); ++i)
 
 872                                 SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val);
 
 876                 /* remember status register for detection of DCD and CTS changes */
 
 877                 scc_last_status_reg[channel] = SCCread(STATUS_REG);
 
 879                 port->c_dcd = 0;        /* Prevent initial 1->0 interrupt */
 
 880                 scc_setsignals (port, 1,1);
 
 881                 local_irq_restore(flags);
 
 884         tty->driver_data = port;
 
 887         retval = gs_init_port(&port->gs);
 
 892         port->gs.flags |= GS_ACTIVE;
 
 893         retval = gs_block_til_ready(port, filp);
 
 900         port->c_dcd = scc_get_CD (port);
 
 902         scc_enable_rx_interrupts(port);
 
 908 static void scc_throttle (struct tty_struct * tty)
 
 910         struct scc_port *port = (struct scc_port *)tty->driver_data;
 
 912         SCC_ACCESS_INIT(port);
 
 914         if (tty->termios->c_cflag & CRTSCTS) {
 
 915                 local_irq_save(flags);
 
 916                 SCCmod(TX_CTRL_REG, ~TCR_RTS, 0);
 
 917                 local_irq_restore(flags);
 
 920                 scc_send_xchar(tty, STOP_CHAR(tty));
 
 924 static void scc_unthrottle (struct tty_struct * tty)
 
 926         struct scc_port *port = (struct scc_port *)tty->driver_data;
 
 928         SCC_ACCESS_INIT(port);
 
 930         if (tty->termios->c_cflag & CRTSCTS) {
 
 931                 local_irq_save(flags);
 
 932                 SCCmod(TX_CTRL_REG, 0xff, TCR_RTS);
 
 933                 local_irq_restore(flags);
 
 936                 scc_send_xchar(tty, START_CHAR(tty));
 
 940 static int scc_ioctl(struct tty_struct *tty, struct file *file,
 
 941                      unsigned int cmd, unsigned long arg)
 
 947 static void scc_break_ctl(struct tty_struct *tty, int break_state)
 
 949         struct scc_port *port = (struct scc_port *)tty->driver_data;
 
 951         SCC_ACCESS_INIT(port);
 
 953         local_irq_save(flags);
 
 954         SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, 
 
 955                         break_state ? TCR_SEND_BREAK : 0);
 
 956         local_irq_restore(flags);
 
 960 /*---------------------------------------------------------------------------
 
 961  * Serial console stuff...
 
 962  *--------------------------------------------------------------------------*/
 
 964 #define scc_delay() do { __asm__ __volatile__ (" nop; nop"); } while (0)
 
 966 static void scc_ch_write (char ch)
 
 968         volatile char *p = NULL;
 
 970 #ifdef CONFIG_MVME147_SCC
 
 972                 p = (volatile char *)M147_SCC_A_ADDR;
 
 974 #ifdef CONFIG_MVME162_SCC
 
 976                 p = (volatile char *)MVME_SCC_A_ADDR;
 
 978 #ifdef CONFIG_BVME6000_SCC
 
 979         if (MACH_IS_BVME6000)
 
 980                 p = (volatile char *)BVME_SCC_A_ADDR;
 
 993 /* The console must be locked when we get here. */
 
 995 static void scc_console_write (struct console *co, const char *str, unsigned count)
 
 999         local_irq_save(flags);
 
1004                         scc_ch_write ('\r');
 
1005                 scc_ch_write (*str++);
 
1007         local_irq_restore(flags);
 
1010 static struct tty_driver *scc_console_device(struct console *c, int *index)
 
1016 static struct console sercons = {
 
1018         .write          = scc_console_write,
 
1019         .device         = scc_console_device,
 
1020         .flags          = CON_PRINTBUFFER,
 
1025 static int __init vme_scc_console_init(void)
 
1027         if (vme_brdtype == VME_TYPE_MVME147 ||
 
1028                         vme_brdtype == VME_TYPE_MVME162 ||
 
1029                         vme_brdtype == VME_TYPE_MVME172 ||
 
1030                         vme_brdtype == VME_TYPE_BVME4000 ||
 
1031                         vme_brdtype == VME_TYPE_BVME6000)
 
1032                 register_console(&sercons);
 
1035 console_initcall(vme_scc_console_init);