linux-old/drivers/char/sh-sci.c
<<
>>
Prefs
   1/* $Id: sh-sci.c,v 1.1.1.1.2.10 2003/09/17 23:38:56 davidm-sf Exp $
   2 *
   3 *  linux/drivers/char/sh-sci.c
   4 *
   5 *  SuperH on-chip serial module support.  (SCI with no FIFO / with FIFO)
   6 *  Copyright (C) 1999, 2000  Niibe Yutaka
   7 *  Copyright (C) 2000  Sugioka Toshinobu
   8 *  Modified to support multiple serial ports. Stuart Menefy (May 2000).
   9 *  Modified to support SecureEdge. David McCullough (2002) 
  10 *  Modified to support SH7300 SCIF. Takashi Kusuda (Jun 2003).
  11 *
  12 * TTY code is based on sx.c (Specialix SX driver) by:
  13 *
  14 *   (C) 1998 R.E.Wolff@BitWizard.nl
  15 *
  16 */
  17
  18#include <linux/config.h>
  19#include <linux/module.h>
  20#include <linux/errno.h>
  21#include <linux/signal.h>
  22#include <linux/sched.h>
  23#include <linux/timer.h>
  24#include <linux/interrupt.h>
  25#include <linux/tty.h>
  26#include <linux/tty_flip.h>
  27#include <linux/serial.h>
  28#include <linux/major.h>
  29#include <linux/string.h>
  30#include <linux/fcntl.h>
  31#include <linux/ptrace.h>
  32#include <linux/ioport.h>
  33#include <linux/mm.h>
  34#include <linux/slab.h>
  35#include <linux/init.h>
  36#include <linux/delay.h>
  37#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SH_KGDB_CONSOLE)
  38#include <linux/console.h>
  39#endif
  40
  41#include <asm/system.h>
  42#include <asm/io.h>
  43#include <asm/irq.h>
  44#include <asm/uaccess.h>
  45#include <asm/bitops.h>
  46
  47#include <linux/generic_serial.h>
  48
  49#ifdef CONFIG_SH_STANDARD_BIOS
  50#include <asm/sh_bios.h>
  51#endif
  52
  53#include "sh-sci.h"
  54
  55#ifdef CONFIG_SH_KGDB
  56#include <asm/kgdb.h>
  57
  58int kgdb_sci_setup(void);
  59static int kgdb_get_char(struct sci_port *port);
  60static void kgdb_put_char(struct sci_port *port, char c);
  61static void kgdb_handle_error(struct sci_port *port);
  62static struct sci_port *kgdb_sci_port;
  63
  64#ifdef CONFIG_SH_KGDB_CONSOLE
  65static struct console kgdbcons;
  66void __init kgdb_console_init(void);
  67#endif /* CONFIG_SH_KGDB_CONSOLE */
  68
  69#endif /* CONFIG_SH_KGDB */
  70
  71#ifdef CONFIG_SERIAL_CONSOLE
  72static struct console sercons;
  73static struct sci_port* sercons_port=0;
  74static int sercons_baud;
  75#ifdef CONFIG_MAGIC_SYSRQ
  76#include <linux/sysrq.h>
  77static int break_pressed;
  78#endif /* CONFIG_MAGIC_SYSRQ */
  79#endif /* CONFIG_SERIAL_CONSOLE */
  80
  81/* Function prototypes */
  82#if !defined(SCIF_ONLY)
  83static void sci_init_pins_sci(struct sci_port* port, unsigned int cflag);
  84#endif
  85#ifndef SCI_ONLY
  86static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag);
  87#if defined(__sh3__) && !defined(CONFIG_CPU_SUBTYPE_SH7300)
  88static void sci_init_pins_irda(struct sci_port* port, unsigned int cflag);
  89#endif
  90#endif
  91static void sci_disable_tx_interrupts(void *ptr);
  92static void sci_enable_tx_interrupts(void *ptr);
  93static void sci_disable_rx_interrupts(void *ptr);
  94static void sci_enable_rx_interrupts(void *ptr);
  95static int  sci_get_CD(void *ptr);
  96static void sci_shutdown_port(void *ptr);
  97static int sci_set_real_termios(void *ptr);
  98static void sci_hungup(void *ptr);
  99static void sci_close(void *ptr);
 100static int sci_chars_in_buffer(void *ptr);
 101static int sci_request_irq(struct sci_port *port);
 102static void sci_free_irq(struct sci_port *port);
 103static int sci_init_drivers(void);
 104
 105static struct tty_driver sci_driver, sci_callout_driver;
 106
 107static struct sci_port sci_ports[SCI_NPORTS] = SCI_INIT;
 108static struct tty_struct *sci_table[SCI_NPORTS] = { NULL, };
 109static struct termios *sci_termios[SCI_NPORTS];
 110static struct termios *sci_termios_locked[SCI_NPORTS];
 111
 112static int sci_refcount;
 113static int sci_debug = 0;
 114
 115#ifdef MODULE
 116MODULE_PARM(sci_debug, "i");
 117#endif
 118
 119#define dprintk(x...) do { if (sci_debug) printk(x); } while(0)
 120
 121#ifdef CONFIG_SERIAL_CONSOLE
 122static void put_char(struct sci_port *port, char c)
 123{
 124        unsigned long flags;
 125        unsigned short status;
 126
 127        save_and_cli(flags);
 128
 129        do
 130                status = sci_in(port, SCxSR);
 131        while (!(status & SCxSR_TDxE(port)));
 132        
 133        sci_out(port, SCxTDR, c);
 134        sci_in(port, SCxSR);            /* Dummy read */
 135        sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
 136
 137        restore_flags(flags);
 138}
 139#endif
 140
 141#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
 142
 143static void handle_error(struct sci_port *port)
 144{                               /* Clear error flags */
 145        sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
 146}
 147
 148static int get_char(struct sci_port *port)
 149{
 150        unsigned long flags;
 151        unsigned short status;
 152        int c;
 153
 154        save_and_cli(flags);
 155        do {
 156                status = sci_in(port, SCxSR);
 157                if (status & SCxSR_ERRORS(port)) {
 158                        handle_error(port);
 159                        continue;
 160                }
 161        } while (!(status & SCxSR_RDxF(port)));
 162        c = sci_in(port, SCxRDR);
 163        sci_in(port, SCxSR);            /* Dummy read */
 164        sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
 165        restore_flags(flags);
 166
 167        return c;
 168}
 169
 170/* Taken from sh-stub.c of GDB 4.18 */
 171static const char hexchars[] = "0123456789abcdef";
 172
 173static __inline__ char highhex(int  x)
 174{
 175        return hexchars[(x >> 4) & 0xf];
 176}
 177
 178static __inline__ char lowhex(int  x)
 179{
 180        return hexchars[x & 0xf];
 181}
 182
 183#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
 184
 185/*
 186 * Send the packet in buffer.  The host gets one chance to read it.
 187 * This routine does not wait for a positive acknowledge.
 188 */
 189
 190#ifdef CONFIG_SERIAL_CONSOLE
 191static void put_string(struct sci_port *port, const char *buffer, int count)
 192{
 193        int i;
 194        const unsigned char *p = buffer;
 195
 196#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
 197        int checksum;
 198        int usegdb=0;
 199
 200#ifdef CONFIG_SH_STANDARD_BIOS
 201        /* This call only does a trap the first time it is
 202         * called, and so is safe to do here unconditionally
 203         */
 204        usegdb |= sh_bios_in_gdb_mode();
 205#endif
 206#ifdef CONFIG_SH_KGDB
 207        usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port));
 208#endif
 209
 210        if (usegdb) {
 211            /*  $<packet info>#<checksum>. */
 212            do {
 213                unsigned char c;
 214                put_char(port, '$');
 215                put_char(port, 'O'); /* 'O'utput to console */
 216                checksum = 'O';
 217
 218                for (i=0; i<count; i++) { /* Don't use run length encoding */
 219                        int h, l;
 220
 221                        c = *p++;
 222                        h = highhex(c);
 223                        l = lowhex(c);
 224                        put_char(port, h);
 225                        put_char(port, l);
 226                        checksum += h + l;
 227                }
 228                put_char(port, '#');
 229                put_char(port, highhex(checksum));
 230                put_char(port, lowhex(checksum));
 231            } while  (get_char(port) != '+');
 232        } else
 233#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
 234        for (i=0; i<count; i++) {
 235                if (*p == 10)
 236                        put_char(port, '\r');
 237                put_char(port, *p++);
 238        }
 239}
 240#endif /* CONFIG_SERIAL_CONSOLE */
 241
 242
 243#if defined(CONFIG_SH_SECUREEDGE5410)
 244
 245struct timer_list sci_timer_struct;
 246static unsigned char sci_dcdstatus[2];
 247
 248/*
 249 * This subroutine is called when the RS_TIMER goes off. It is used
 250 * to monitor the state of the DCD lines - since they have no edge
 251 * sensors and interrupt generators.
 252 */
 253static void sci_timer(unsigned long data)
 254{
 255        unsigned short s, i;
 256        unsigned char  dcdstatus[2];
 257
 258        s = SECUREEDGE_READ_IOPORT();
 259        dcdstatus[0] = !(s & 0x10);
 260        dcdstatus[1] = !(s & 0x1);
 261
 262        for (i = 0; i < 2; i++) {
 263                if (dcdstatus[i] != sci_dcdstatus[i]) {
 264                        if (sci_ports[i].gs.count != 0) {
 265                                if (sci_ports[i].gs.flags & ASYNC_CHECK_CD) {
 266                                        if (dcdstatus[i]) { /* DCD has gone high */
 267                                                wake_up_interruptible(&sci_ports[i].gs.open_wait);
 268                                        } else if (!((sci_ports[i].gs.flags&ASYNC_CALLOUT_ACTIVE) &&
 269                                                        (sci_ports[i].gs.flags & ASYNC_CALLOUT_NOHUP))) {
 270                                                if (sci_ports[i].gs.tty)
 271                                                        tty_hangup(sci_ports[i].gs.tty);
 272                                        }
 273                                }
 274                        }
 275                }
 276                sci_dcdstatus[i] = dcdstatus[i];
 277        }
 278
 279        sci_timer_struct.expires = jiffies + HZ/25;
 280        add_timer(&sci_timer_struct);
 281}
 282
 283#endif
 284
 285
 286
 287
 288#ifdef CONFIG_SH_KGDB
 289
 290/* Is the SCI ready, ie is there a char waiting? */
 291static int kgdb_is_char_ready(struct sci_port *port)
 292{
 293        unsigned short status = sci_in(port, SCxSR);
 294
 295        if (status & (SCxSR_ERRORS(port) | SCxSR_BRK(port)))
 296                kgdb_handle_error(port);
 297
 298        return (status & SCxSR_RDxF(port));
 299}
 300
 301/* Write a char */
 302static void kgdb_put_char(struct sci_port *port, char c)
 303{
 304        unsigned short status;
 305
 306        do
 307                status = sci_in(port, SCxSR);
 308        while (!(status & SCxSR_TDxE(port)));
 309
 310        sci_out(port, SCxTDR, c);
 311        sci_in(port, SCxSR);    /* Dummy read */
 312        sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
 313}
 314
 315/* Get a char if there is one, else ret -1 */
 316static int kgdb_get_char(struct sci_port *port)
 317{
 318        int c;
 319
 320        if (kgdb_is_char_ready(port) == 0)
 321                c = -1;
 322        else {
 323                c = sci_in(port, SCxRDR);
 324                sci_in(port, SCxSR);    /* Dummy read */
 325                sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
 326        }
 327
 328        return c;
 329}
 330
 331/* Called from kgdbstub.c to get a character, i.e. is blocking */
 332static int kgdb_sci_getchar(void)
 333{
 334        volatile int c;
 335
 336        /* Keep trying to read a character, this could be neater */
 337        while ((c = kgdb_get_char(kgdb_sci_port)) < 0);
 338
 339        return c;
 340}
 341
 342/* Called from kgdbstub.c to put a character, just a wrapper */
 343static void kgdb_sci_putchar(int c)
 344{
 345
 346        kgdb_put_char(kgdb_sci_port, c);
 347}
 348
 349/* Clear any errors on the SCI */
 350static void kgdb_handle_error(struct sci_port *port)
 351{
 352        sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));  /* Clear error flags */
 353}
 354
 355/* Breakpoint if there's a break sent on the serial port */
 356static void kgdb_break_interrupt(int irq, void *ptr, struct pt_regs *regs)
 357{
 358        struct sci_port *port = ptr;
 359        unsigned short status = sci_in(port, SCxSR);
 360
 361        if (status & SCxSR_BRK(port)) {
 362
 363                /* Break into the debugger if a break is detected */
 364                BREAKPOINT();
 365
 366                /* Clear */
 367                sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
 368                return;
 369        }
 370}
 371
 372#endif /* CONFIG_SH_KGDB */
 373
 374static struct real_driver sci_real_driver = {
 375        sci_disable_tx_interrupts,
 376        sci_enable_tx_interrupts,
 377        sci_disable_rx_interrupts,
 378        sci_enable_rx_interrupts,
 379        sci_get_CD,
 380        sci_shutdown_port,
 381        sci_set_real_termios,
 382        sci_chars_in_buffer,
 383        sci_close,
 384        sci_hungup,
 385        NULL
 386};
 387
 388#if defined(SCI_ONLY) || defined(SCI_AND_SCIF)
 389static void sci_init_pins_sci(struct sci_port* port, unsigned int cflag)
 390{
 391}
 392#endif
 393
 394#if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
 395#if defined(__sh3__)
 396/* For SH7300, SH7707, SH7709, SH7709A, SH7729 */
 397static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag)
 398{
 399        unsigned int fcr_val = 0;
 400
 401#if !defined(CONFIG_CPU_SUBTYPE_SH7300) /* SH7300 doesn't use RTS/CTS */
 402        {
 403                unsigned short data;
 404
 405                /* We need to set SCPCR to enable RTS/CTS */
 406                data = ctrl_inw(SCPCR);
 407                /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
 408                ctrl_outw(data&0x0cff, SCPCR);
 409        }
 410        if (cflag & CRTSCTS)
 411                fcr_val |= SCFCR_MCE;
 412        else {
 413                unsigned short data;
 414
 415                /* We need to set SCPCR to enable RTS/CTS */
 416                data = ctrl_inw(SCPCR);
 417                /* Clear out SCP7MD1,0, SCP4MD1,0,
 418                   Set SCP6MD1,0 = {01} (output)  */
 419                ctrl_outw((data&0x0cff)|0x1000, SCPCR);
 420
 421                data = ctrl_inb(SCPDR);
 422                /* Set /RTS2 (bit6) = 0 */
 423                ctrl_outb(data&0xbf, SCPDR);
 424        }
 425#endif
 426        sci_out(port, SCFCR, fcr_val);
 427}
 428
 429static void sci_init_pins_irda(struct sci_port* port, unsigned int cflag)
 430{
 431        unsigned int fcr_val = 0;
 432
 433        if (cflag & CRTSCTS)
 434                fcr_val |= SCFCR_MCE;
 435
 436        sci_out(port, SCFCR, fcr_val);
 437}
 438
 439#else
 440
 441/* For SH7750 */
 442static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag)
 443{
 444        unsigned int fcr_val = 0;
 445
 446        if (cflag & CRTSCTS) {
 447                fcr_val |= SCFCR_MCE;
 448        } else {
 449                sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */
 450        }
 451        sci_out(port, SCFCR, fcr_val);
 452}
 453
 454#endif
 455#endif /* SCIF_ONLY || SCI_AND_SCIF */
 456
 457static void sci_setsignals(struct sci_port *port, int dtr, int rts)
 458{
 459        /* This routine is used for seting signals of: DTR, DCD, CTS/RTS */
 460        /* We use SCIF's hardware for CTS/RTS, so don't need any for that. */
 461        /* If you have signals for DTR and DCD, please implement here. */
 462
 463#if defined(CONFIG_SH_SECUREEDGE5410)
 464        int flags;
 465
 466        save_and_cli(flags);
 467        if (port == &sci_ports[1]) { /* port 1 only */
 468                if (dtr == 0)
 469                        SECUREEDGE_WRITE_IOPORT(0x0080, 0x0080);
 470                else if (dtr == 1)
 471                        SECUREEDGE_WRITE_IOPORT(0x0000, 0x0080);
 472        }
 473        if (port == &sci_ports[0]) { /* port 0 only */
 474                if (dtr == 0)
 475                        SECUREEDGE_WRITE_IOPORT(0x0200, 0x0200);
 476                else if (dtr == 1)
 477                        SECUREEDGE_WRITE_IOPORT(0x0000, 0x0200);
 478                if (rts == 0)
 479                        SECUREEDGE_WRITE_IOPORT(0x0100, 0x0100);
 480                else if (rts == 1)
 481                        SECUREEDGE_WRITE_IOPORT(0x0000, 0x0100);
 482        }
 483        restore_flags(flags);
 484#endif
 485}
 486
 487static int sci_getsignals(struct sci_port *port)
 488{
 489        /* This routine is used for geting signals of: DTR, DCD, DSR, RI,
 490           and CTS/RTS */
 491
 492#if defined(CONFIG_SH_SECUREEDGE5410)
 493        if (port == &sci_ports[1]) { /* port 1 only */
 494                unsigned short s = SECUREEDGE_READ_IOPORT();
 495                int rc = TIOCM_RTS|TIOCM_DSR|TIOCM_CTS;
 496
 497                if ((s & 0x0001) == 0)
 498                        rc |= TIOCM_CAR;
 499                if ((SECUREEDGE_READ_IOPORT() & 0x0080) == 0)
 500                        rc |= TIOCM_DTR;
 501                return(rc);
 502        }
 503        if (port == &sci_ports[0]) { /* port 0 only */
 504                unsigned short s = SECUREEDGE_READ_IOPORT();
 505                int rc = TIOCM_DSR;
 506
 507                if ((s & 0x0010) == 0)
 508                        rc |= TIOCM_CAR;
 509                if ((s & 0x0004) == 0)
 510                        rc |= TIOCM_CTS;
 511                if ((SECUREEDGE_READ_IOPORT() & 0x0200) == 0)
 512                        rc |= TIOCM_DTR;
 513                if ((SECUREEDGE_READ_IOPORT() & 0x0100) == 0)
 514                        rc |= TIOCM_RTS;
 515                return(rc);
 516        }
 517#endif
 518
 519        return TIOCM_DTR|TIOCM_RTS|TIOCM_DSR;
 520}
 521
 522static void sci_set_baud(struct sci_port *port, int baud)
 523{
 524        int t;
 525
 526        switch (baud) {
 527        case 0:
 528                t = -1;
 529                break;
 530        case 2400:
 531                t = BPS_2400;
 532                break;
 533        case 4800:
 534                t = BPS_4800;
 535                break;
 536        case 9600:
 537                t = BPS_9600;
 538                break;
 539        case 19200:
 540                t = BPS_19200;
 541                break;
 542        case 38400:
 543                t = BPS_38400;
 544                break;
 545        case 57600:
 546                t = BPS_57600;
 547                break;
 548        case 230400:
 549                if (BPS_230400 != BPS_115200) {
 550                        t = BPS_230400;
 551                        break;
 552                }
 553        default:
 554                printk(KERN_INFO "sci: unsupported baud rate: %d, using 115200 instead.\n", baud);
 555        case 115200:
 556                t = BPS_115200;
 557                break;
 558        }
 559
 560        if (t > 0) {
 561                sci_setsignals (port, 1, -1);
 562                if(t >= 256) {
 563                        sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
 564                        t >>= 2;
 565                } else {
 566                        sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3);
 567                }
 568                sci_out(port, SCBRR, t);
 569                udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
 570        } else {
 571                sci_setsignals (port, 0, -1);
 572        }
 573}
 574
 575static void sci_set_termios_cflag(struct sci_port *port, int cflag, int baud)
 576{
 577        unsigned int status;
 578        unsigned int smr_val;
 579
 580        do
 581                status = sci_in(port, SCxSR);
 582        while (!(status & SCxSR_TEND(port)));
 583
 584        sci_out(port, SCSCR, 0x00);     /* TE=0, RE=0, CKE1=0 */
 585
 586        if (port->type == PORT_SCIF) {
 587#if defined(CONFIG_CPU_SUBTYPE_SH7300)
 588                sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST | SCFCR_TCRST);
 589#else
 590                sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
 591#endif
 592        }
 593
 594        smr_val = sci_in(port, SCSMR) & 3;
 595        if ((cflag & CSIZE) == CS7)
 596                smr_val |= 0x40;
 597        if (cflag & PARENB)
 598                smr_val |= 0x20;
 599        if (cflag & PARODD)
 600                smr_val |= 0x30;
 601        if (cflag & CSTOPB)
 602                smr_val |= 0x08;
 603        sci_out(port, SCSMR, smr_val);
 604        sci_set_baud(port, baud);
 605
 606        port->init_pins(port, cflag);
 607        sci_out(port, SCSCR, SCSCR_INIT(port));
 608
 609        if (cflag & CLOCAL)
 610                port->gs.flags &= ~ASYNC_CHECK_CD;
 611        else
 612                port->gs.flags |= ASYNC_CHECK_CD;
 613}
 614
 615static int sci_set_real_termios(void *ptr)
 616{
 617        struct sci_port *port = ptr;
 618
 619        if (port->old_cflag != port->gs.tty->termios->c_cflag) {
 620                port->old_cflag = port->gs.tty->termios->c_cflag;
 621                sci_set_termios_cflag(port, port->old_cflag, port->gs.baud);
 622                sci_enable_rx_interrupts(port);
 623        }
 624
 625        return 0;
 626}
 627
 628/* ********************************************************************** *
 629 *                   the interrupt related routines                       *
 630 * ********************************************************************** */
 631
 632/*
 633 * This routine is used by the interrupt handler to schedule
 634 * processing in the software interrupt portion of the driver.
 635 */
 636static inline void sci_sched_event(struct sci_port *port, int event)
 637{
 638        port->event |= 1 << event;
 639        queue_task(&port->tqueue, &tq_immediate);
 640        mark_bh(IMMEDIATE_BH);
 641}
 642
 643static void sci_transmit_chars(struct sci_port *port)
 644{
 645        unsigned int count, i;
 646        unsigned int txroom;
 647        unsigned long flags;
 648        unsigned short status;
 649        unsigned short ctrl;
 650        unsigned char c;
 651
 652        status = sci_in(port, SCxSR);
 653        if (!(status & SCxSR_TDxE(port))) {
 654                save_and_cli(flags);
 655                ctrl = sci_in(port, SCSCR);
 656                if (port->gs.xmit_cnt == 0) {
 657                        ctrl &= ~SCI_CTRL_FLAGS_TIE;
 658                        port->gs.flags &= ~GS_TX_INTEN;
 659                } else
 660                        ctrl |= SCI_CTRL_FLAGS_TIE;
 661                sci_out(port, SCSCR, ctrl);
 662                restore_flags(flags);
 663                return;
 664        }
 665
 666        while (1) {
 667                count = port->gs.xmit_cnt;
 668                if (port->type == PORT_SCIF) {
 669#if defined(CONFIG_CPU_SUBTYPE_SH7300)
 670                        txroom = 64 - (sci_in(port, SCFDR)>>8);
 671#else
 672                        txroom = 16 - (sci_in(port, SCFDR)>>8);
 673#endif
 674                } else {
 675                        txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0;
 676                }
 677                if (count > txroom)
 678                        count = txroom;
 679
 680                /* Don't copy past the end of the source buffer */
 681                if (count > SERIAL_XMIT_SIZE - port->gs.xmit_tail)
 682                        count = SERIAL_XMIT_SIZE - port->gs.xmit_tail;
 683
 684                /* If for one reason or another, we can't copy more data, we're done! */
 685                if (count == 0)
 686                        break;
 687
 688                for (i=0; i<count; i++) {
 689                        c = port->gs.xmit_buf[port->gs.xmit_tail + i];
 690                        sci_out(port, SCxTDR, c);
 691                }
 692                sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
 693
 694                port->icount.tx += count;
 695
 696                /* Update the kernel buffer end */
 697                port->gs.xmit_tail = (port->gs.xmit_tail + count) & (SERIAL_XMIT_SIZE-1);
 698
 699                /* This one last. (this is essential)
 700                   It would allow others to start putting more data into the buffer! */
 701                port->gs.xmit_cnt -= count;
 702        }
 703
 704        if (port->gs.xmit_cnt <= port->gs.wakeup_chars)
 705                sci_sched_event(port, SCI_EVENT_WRITE_WAKEUP);
 706
 707        save_and_cli(flags);
 708        ctrl = sci_in(port, SCSCR);
 709        if (port->gs.xmit_cnt == 0) {
 710                ctrl &= ~SCI_CTRL_FLAGS_TIE;
 711                port->gs.flags &= ~GS_TX_INTEN;
 712        } else {
 713                if (port->type == PORT_SCIF) {
 714                        sci_in(port, SCxSR); /* Dummy read */
 715                        sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
 716                }
 717                ctrl |= SCI_CTRL_FLAGS_TIE;
 718        }
 719        sci_out(port, SCSCR, ctrl);
 720        restore_flags(flags);
 721}
 722
 723/* On SH3, SCIF may read end-of-break as a space->mark char */
 724#define STEPFN(c)  ({int __c=(c); (((__c-1)|(__c)) == -1); })
 725
 726static inline void sci_receive_chars(struct sci_port *port,
 727                                     struct pt_regs *regs)
 728{
 729        int count;
 730        struct tty_struct *tty;
 731        int copied=0;
 732        unsigned short status;
 733
 734        status = sci_in(port, SCxSR);
 735        if (!(status & SCxSR_RDxF(port)))
 736                return;
 737
 738        tty = port->gs.tty;
 739
 740        while (1) {
 741                if (port->type == PORT_SCIF) {
 742#if defined(CONFIG_CPU_SUBTYPE_SH7300)
 743                        count = sci_in(port, SCFDR)&0x007f;
 744#else
 745                        count = sci_in(port, SCFDR)&0x001f;
 746#endif
 747                } else {
 748                        count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0;
 749                }
 750
 751                /* we must clear RDF or we get stuck in the interrupt for ever */
 752                sci_in(port, SCxSR); /* dummy read */
 753                sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
 754
 755                /* If for any reason we can't copy more data, we're done! */
 756                if (count == 0)
 757                        break;
 758
 759                if (port->type == PORT_SCI) {
 760                        if (tty->flip.count < TTY_FLIPBUF_SIZE) {
 761                                *tty->flip.char_buf_ptr++ = sci_in(port, SCxRDR);
 762                                *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
 763                                tty->flip.count++;
 764                                port->icount.rx++;
 765                                copied++;
 766                                count--;
 767                        }
 768                } else {
 769                        while (count > 0 && tty->flip.count < TTY_FLIPBUF_SIZE){
 770                                char c = sci_in(port, SCxRDR);
 771                                status = sci_in(port, SCxSR);
 772
 773#if defined(__SH3__)
 774                                /* Skip "chars" during break */
 775                                if (port->break_flag) {
 776                                        if ((c == 0) &&
 777                                            (status & SCxSR_FER(port))) {
 778                                                count--;
 779                                                continue;
 780                                        }
 781                                        /* Nonzero => end-of-break */
 782                                        dprintk("scif: debounce<%02x>\n", c);
 783                                        port->break_flag = 0;
 784                                        if (STEPFN(c)) {
 785                                                count--;
 786                                                continue;
 787                                        }
 788                                }
 789#endif /* __SH3__ */
 790#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 791                                if (break_pressed && (port == sercons_port)) {
 792                                        if (c != 0 &&
 793                                            time_before(jiffies,
 794                                                        break_pressed + HZ*5)) {
 795                                                handle_sysrq(c, regs,
 796                                                             NULL, NULL);
 797                                                break_pressed = 0;
 798                                                count--;
 799                                                continue;
 800                                        } else if (c != 0) {
 801                                                break_pressed = 0;
 802                                        }
 803                                }
 804#endif /* CONFIG_SERIAL_CONSOLE && CONFIG_MAGIC_SYSRQ */
 805
 806                                /* Store data and status */
 807                                *tty->flip.char_buf_ptr++ = c;
 808
 809                                if (status&SCxSR_FER(port)) {
 810                                        *tty->flip.flag_buf_ptr++ = TTY_FRAME;
 811                                        dprintk("sci: frame error\n");
 812                                } else if (status&SCxSR_PER(port)) {
 813                                        *tty->flip.flag_buf_ptr++ = TTY_PARITY;
 814                                        dprintk("sci: parity error\n");
 815                                } else {
 816                                        *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
 817                                }
 818                                tty->flip.count++;
 819                                port->icount.rx++;
 820                                copied++;
 821                                count--;
 822                        }
 823                }
 824
 825                /* drop any remaining chars,  we are full */
 826                if (count > 0) {
 827                        /* force an overrun error on last received char */
 828                        tty->flip.flag_buf_ptr[TTY_FLIPBUF_SIZE - 1] = TTY_OVERRUN;
 829                        while (count-- > 0)
 830                                (void) sci_in(port, SCxRDR);
 831                }
 832        }
 833
 834        if (copied)
 835                /* Tell the rest of the system the news. New characters! */
 836                tty_flip_buffer_push(tty);
 837        else {
 838                sci_in(port, SCxSR); /* dummy read */
 839                sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
 840        }
 841}
 842
 843static inline int sci_handle_errors(struct sci_port *port)
 844{
 845        int copied = 0;
 846        unsigned short status = sci_in(port, SCxSR);
 847        struct tty_struct *tty = port->gs.tty;
 848
 849        if (status&SCxSR_ORER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
 850                /* overrun error */
 851                copied++;
 852                *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
 853                dprintk("sci: overrun error\n");
 854        }
 855
 856        if (status&SCxSR_FER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
 857                if (sci_rxd_in(port) == 0) {
 858                        /* Notify of BREAK */
 859                        copied++;
 860                        *tty->flip.flag_buf_ptr++ = TTY_BREAK;
 861                        dprintk("sci: BREAK detected\n");
 862                }
 863                else {
 864                        /* frame error */
 865                        copied++;
 866                        *tty->flip.flag_buf_ptr++ = TTY_FRAME;
 867                        dprintk("sci: frame error\n");
 868                }
 869        }
 870
 871        if (status&SCxSR_PER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
 872                /* parity error */
 873                copied++;
 874                *tty->flip.flag_buf_ptr++ = TTY_PARITY;
 875                dprintk("sci: parity error\n");
 876        }
 877
 878        if (copied) {
 879                tty->flip.count += copied;
 880                tty_flip_buffer_push(tty);
 881        }
 882
 883        return copied;
 884}
 885
 886static inline int sci_handle_breaks(struct sci_port *port)
 887{
 888        int copied = 0;
 889        unsigned short status = sci_in(port, SCxSR);
 890        struct tty_struct *tty = port->gs.tty;
 891
 892        if (status&SCxSR_BRK(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
 893#if defined(__SH3__)
 894                /* Debounce break */
 895                if (port->break_flag)
 896                        goto break_continue;
 897                port->break_flag = 1;
 898#endif
 899#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 900                if (port == sercons_port) {
 901                        if (break_pressed == 0) {
 902                                break_pressed = jiffies;
 903                                dprintk("sci: implied sysrq\n");
 904                                goto break_continue;
 905                        }
 906                        /* Double break implies a real break */
 907                        break_pressed = 0;
 908                }
 909#endif
 910                /* Notify of BREAK */
 911                copied++;
 912                *tty->flip.flag_buf_ptr++ = TTY_BREAK;
 913                dprintk("sci: BREAK detected\n");
 914        }
 915#if defined(CONFIG_CPU_SH3) || defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 916 break_continue:
 917#endif
 918
 919#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined (CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_ST40)
 920        /* XXX: Handle SCIF overrun error */
 921        if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
 922                sci_out(port, SCLSR, 0);
 923                if(tty->flip.count<TTY_FLIPBUF_SIZE) {
 924                        copied++;
 925                        *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
 926                        dprintk("sci: overrun error\n");
 927                }
 928        }
 929#endif
 930
 931        if (copied) {
 932                tty->flip.count += copied;
 933                tty_flip_buffer_push(tty);
 934        }
 935
 936        return copied;
 937}
 938
 939static void sci_rx_interrupt(int irq, void *ptr, struct pt_regs *regs)
 940{
 941        struct sci_port *port = ptr;
 942
 943        if (port->gs.flags & GS_ACTIVE)
 944                if (!(port->gs.flags & SCI_RX_THROTTLE)) {
 945                        sci_receive_chars(port, regs);
 946                        return;
 947                }
 948        sci_disable_rx_interrupts(port);
 949}
 950
 951static void sci_tx_interrupt(int irq, void *ptr, struct pt_regs *regs)
 952{
 953        struct sci_port *port = ptr;
 954
 955        if (port->gs.flags & GS_ACTIVE)
 956                sci_transmit_chars(port);
 957        else {
 958                sci_disable_tx_interrupts(port);
 959        }
 960}
 961
 962static void sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs)
 963{
 964        struct sci_port *port = ptr;
 965
 966        /* Handle errors */
 967        if (port->type == PORT_SCI) {
 968                if(sci_handle_errors(port)) {
 969                        /* discard character in rx buffer */
 970                        sci_in(port, SCxSR);
 971                        sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
 972                }
 973        }
 974        else
 975                sci_rx_interrupt(irq, ptr, regs);
 976                
 977        sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
 978
 979        /* Kick the transmission */
 980        sci_tx_interrupt(irq, ptr, regs);
 981}
 982
 983static void sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs)
 984{
 985        struct sci_port *port = ptr;
 986
 987        /* Handle BREAKs */
 988        sci_handle_breaks(port);
 989        sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
 990}
 991
 992static void sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs)
 993{
 994        unsigned short ssr_status, scr_status;
 995        struct sci_port *port = ptr;
 996
 997        ssr_status=sci_in(port,SCxSR);
 998        scr_status=sci_in(port,SCSCR);
 999
1000        if((ssr_status&0x0020) && (scr_status&0x0080)){ /* Tx Interrupt */
1001                sci_tx_interrupt(irq, ptr, regs);
1002        }
1003        if((ssr_status&0x0002) && (scr_status&0x0040)){ /* Rx Interrupt */
1004                sci_rx_interrupt(irq, ptr, regs);
1005        }
1006        if((ssr_status&0x0080) && (scr_status&0x0400)){ /* Error Interrupt */
1007                sci_er_interrupt(irq, ptr, regs);
1008        }
1009        if((ssr_status&0x0010) && (scr_status&0x0200)){ /* Break Interrupt */
1010                sci_br_interrupt(irq, ptr, regs);
1011        }
1012}
1013
1014static void do_softint(void *private_)
1015{
1016        struct sci_port *port = (struct sci_port *) private_;
1017        struct tty_struct       *tty;
1018        
1019        tty = port->gs.tty;
1020        if (!tty)
1021                return;
1022
1023        if (test_and_clear_bit(SCI_EVENT_WRITE_WAKEUP, &port->event)) {
1024                tty_wakeup(tty);
1025        }
1026}
1027
1028/* ********************************************************************** *
1029 *                Here are the routines that actually                     *
1030 *              interface with the generic_serial driver                  *
1031 * ********************************************************************** */
1032
1033static void sci_disable_tx_interrupts(void *ptr)
1034{
1035        struct sci_port *port = ptr;
1036        unsigned long flags;
1037        unsigned short ctrl;
1038
1039        /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
1040        save_and_cli(flags);
1041        ctrl = sci_in(port, SCSCR);
1042        ctrl &= ~SCI_CTRL_FLAGS_TIE;
1043        sci_out(port, SCSCR, ctrl);
1044        restore_flags(flags);
1045}
1046
1047static void sci_enable_tx_interrupts(void *ptr)
1048{
1049        struct sci_port *port = ptr; 
1050
1051        disable_irq(port->irqs[SCIx_TXI_IRQ]);
1052        sci_transmit_chars(port);
1053        enable_irq(port->irqs[SCIx_TXI_IRQ]);
1054}
1055
1056static void sci_disable_rx_interrupts(void * ptr)
1057{
1058        struct sci_port *port = ptr;
1059        unsigned long flags;
1060        unsigned short ctrl;
1061
1062        /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
1063        save_and_cli(flags);
1064        ctrl = sci_in(port, SCSCR);
1065        ctrl &= ~SCI_CTRL_FLAGS_RIE;
1066        sci_out(port, SCSCR, ctrl);
1067        restore_flags(flags);
1068}
1069
1070static void sci_enable_rx_interrupts(void * ptr)
1071{
1072        struct sci_port *port = ptr;
1073        unsigned long flags;
1074        unsigned short ctrl;
1075
1076        /* Set RIE (Receive Interrupt Enable) bit in SCSCR */
1077        save_and_cli(flags);
1078        ctrl = sci_in(port, SCSCR);
1079        ctrl |= SCI_CTRL_FLAGS_RIE;
1080        sci_out(port, SCSCR, ctrl);
1081        restore_flags(flags);
1082}
1083
1084static int sci_get_CD(void * ptr)
1085{
1086        /* If you have signal for CD (Carrier Detect), please change here. */
1087
1088#if defined(CONFIG_SH_SECUREEDGE5410)
1089        struct sci_port *port = ptr;
1090
1091        if (port == &sci_ports[0] || port == &sci_ports[1])
1092                if ((sci_getsignals(port) & TIOCM_CAR) == 0)
1093                        return 0;
1094#endif
1095
1096        return 1;
1097}
1098
1099static int sci_chars_in_buffer(void * ptr)
1100{
1101        struct sci_port *port = ptr;
1102
1103        if (port->type == PORT_SCIF) {
1104                return (sci_in(port, SCFDR) >> 8) + ((sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1);
1105        } else {
1106                return (sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1;
1107        }
1108}
1109
1110static void sci_shutdown_port(void * ptr)
1111{
1112        struct sci_port *port = ptr; 
1113
1114        port->gs.flags &= ~ GS_ACTIVE;
1115        if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL)
1116                sci_setsignals(port, 0, 0);
1117        sci_free_irq(port);
1118}
1119
1120/* ********************************************************************** *
1121 *                Here are the routines that actually                     *
1122 *               interface with the rest of the system                    *
1123 * ********************************************************************** */
1124
1125static int sci_open(struct tty_struct * tty, struct file * filp)
1126{
1127        struct sci_port *port;
1128        int retval = 0, line;
1129
1130        line = MINOR(tty->device) - SCI_MINOR_START;
1131
1132        if ((line < 0) || (line >= SCI_NPORTS))
1133                return -ENODEV;
1134
1135        port = &sci_ports[line];
1136
1137#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
1138        if (port->base == 0) {
1139                port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
1140                if (!port->base)
1141                        goto failed_1;
1142        }
1143#endif
1144
1145        tty->driver_data = port;
1146        port->gs.tty = tty;
1147        port->gs.count++;
1148
1149        port->event = 0;
1150        port->tqueue.routine = do_softint;
1151        port->tqueue.data = port;
1152        port->break_flag = 0;
1153
1154        if (port->gs.count == 1) {
1155                MOD_INC_USE_COUNT;
1156
1157                retval = sci_request_irq(port);
1158                if (retval) {
1159                        goto failed_1;
1160                }
1161        }
1162
1163        /*
1164         * Start up serial port
1165         */
1166        retval = gs_init_port(&port->gs);
1167        if (retval) {
1168                goto failed_2;
1169        }
1170
1171        port->gs.flags |= GS_ACTIVE;
1172        sci_setsignals(port, 1,1);
1173
1174        retval = gs_block_til_ready(port, filp);
1175
1176        if (retval) {
1177                goto failed_2;
1178        }
1179
1180        if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
1181                if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
1182                        *tty->termios = port->gs.normal_termios;
1183                else 
1184                        *tty->termios = port->gs.callout_termios;
1185                sci_set_real_termios(port);
1186        }
1187
1188#ifdef CONFIG_SERIAL_CONSOLE
1189        if (sercons.cflag && sercons.index == line) {
1190                tty->termios->c_cflag = sercons.cflag;
1191                port->gs.baud = sercons_baud;
1192                sercons.cflag = 0;
1193                sci_set_real_termios(port);
1194        }
1195#endif
1196
1197#ifdef CONFIG_SH_KGDB_CONSOLE
1198        if (kgdbcons.cflag && kgdbcons.index == line) {
1199                tty->termios->c_cflag = kgdbcons.cflag;
1200                port->gs.baud = kgdb_baud;
1201                sercons.cflag = 0;
1202                sci_set_real_termios(port);
1203        }
1204#elif CONFIG_SH_KGDB
1205        /* Even for non-console, may defer to kgdb */
1206        if (port == kgdb_sci_port && kgdb_in_gdb_mode) {
1207                tty->termios->c_cflag = kgdb_cflag;
1208                port->gs.baud = kgdb_baud;
1209                sercons.cflag = 0;
1210                sci_set_real_termios(port);
1211        }
1212#endif /* CONFIG_SH_KGDB */
1213
1214        sci_enable_rx_interrupts(port);
1215
1216        port->gs.session = current->session;
1217        port->gs.pgrp = current->pgrp;
1218
1219        return 0;
1220
1221failed_2:
1222        sci_free_irq(port);
1223failed_1:
1224        MOD_DEC_USE_COUNT;
1225        port->gs.count--;
1226        return retval;
1227}
1228
1229static void sci_hungup(void *ptr)
1230{
1231        MOD_DEC_USE_COUNT;
1232}
1233
1234static void sci_close(void *ptr)
1235{
1236        MOD_DEC_USE_COUNT;
1237}
1238
1239static int sci_ioctl(struct tty_struct * tty, struct file * filp, 
1240                     unsigned int cmd, unsigned long arg)
1241{
1242        int rc;
1243        struct sci_port *port = tty->driver_data;
1244        int ival;
1245
1246        rc = 0;
1247        switch (cmd) {
1248        case TIOCGSOFTCAR:
1249                rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
1250                              (unsigned int *) arg);
1251                break;
1252        case TIOCSSOFTCAR:
1253                if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
1254                        tty->termios->c_cflag =
1255                                (tty->termios->c_cflag & ~CLOCAL) |
1256                                (ival ? CLOCAL : 0);
1257                break;
1258        case TIOCGSERIAL:
1259                if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
1260                                      sizeof(struct serial_struct))) == 0)
1261                        rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
1262                break;
1263        case TIOCSSERIAL:
1264                if ((rc = verify_area(VERIFY_READ, (void *) arg,
1265                                      sizeof(struct serial_struct))) == 0)
1266                        rc = gs_setserial(&port->gs,
1267                                          (struct serial_struct *) arg);
1268                break;
1269        case TIOCMGET:
1270                ival = sci_getsignals(port);
1271                rc = put_user(ival, (unsigned int *) arg);
1272                break;
1273        case TIOCMBIS:
1274                if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
1275                        sci_setsignals(port, ((ival & TIOCM_DTR) ? 1 : -1),
1276                                             ((ival & TIOCM_RTS) ? 1 : -1));
1277                break;
1278        case TIOCMBIC:
1279                if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
1280                        sci_setsignals(port, ((ival & TIOCM_DTR) ? 0 : -1),
1281                                             ((ival & TIOCM_RTS) ? 0 : -1));
1282                break;
1283        case TIOCMSET:
1284                if ((rc = get_user(ival, (unsigned int *)arg)) == 0)
1285                        sci_setsignals(port, ((ival & TIOCM_DTR) ? 1 : 0),
1286                                             ((ival & TIOCM_RTS) ? 1 : 0));
1287                break;
1288
1289        default:
1290                rc = -ENOIOCTLCMD;
1291                break;
1292        }
1293
1294        return rc;
1295}
1296
1297static void sci_throttle(struct tty_struct * tty)
1298{
1299        struct sci_port *port = (struct sci_port *)tty->driver_data;
1300
1301        /* If the port is using any type of input flow
1302         * control then throttle the port.
1303         */
1304        if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty)) )
1305                port->gs.flags |= SCI_RX_THROTTLE;
1306}
1307
1308static void sci_unthrottle(struct tty_struct * tty)
1309{
1310        struct sci_port *port = (struct sci_port *)tty->driver_data;
1311
1312        /* Always unthrottle even if flow control is not enabled on
1313         * this port in case we disabled flow control while the port
1314         * was throttled
1315         */
1316        port->gs.flags &= ~SCI_RX_THROTTLE;
1317        sci_enable_rx_interrupts(port);
1318        return;
1319}
1320
1321#ifdef CONFIG_PROC_FS
1322static int sci_read_proc(char *page, char **start, off_t off, int count,
1323                         int *eof, void *data)
1324{
1325        int i;
1326        struct sci_port *port;
1327        int len = 0;
1328        
1329        len += sprintf(page, "sciinfo:0.1\n");
1330        for (i = 0; i < SCI_NPORTS && len < 4000; i++) {
1331                port = &sci_ports[i];
1332                len += sprintf(page+len, "%d: uart:%s address: %08x", i,
1333                               (port->type == PORT_SCI) ? "SCI" : "SCIF",
1334                               port->base);
1335                len += sprintf(page+len, " baud:%d", port->gs.baud);
1336                len += sprintf(page+len, " tx:%d rx:%d",
1337                               port->icount.tx, port->icount.rx);
1338
1339                if (port->icount.frame)
1340                        len += sprintf(page+len, " fe:%d", port->icount.frame);
1341                if (port->icount.parity)
1342                        len += sprintf(page+len, " pe:%d", port->icount.parity);
1343                if (port->icount.brk)
1344                        len += sprintf(page+len, " brk:%d", port->icount.brk);
1345                if (port->icount.overrun)
1346                        len += sprintf(page+len, " oe:%d", port->icount.overrun);
1347                len += sprintf(page+len, "\n");
1348        }
1349        return len;
1350}
1351#endif
1352
1353/* ********************************************************************** *
1354 *                    Here are the initialization routines.               *
1355 * ********************************************************************** */
1356
1357static int sci_init_drivers(void)
1358{
1359        int error;
1360        struct sci_port *port;
1361
1362        memset(&sci_driver, 0, sizeof(sci_driver));
1363        sci_driver.magic = TTY_DRIVER_MAGIC;
1364        sci_driver.driver_name = "sci";
1365#ifdef CONFIG_DEVFS_FS
1366        sci_driver.name = "ttsc/%d";
1367#else
1368        sci_driver.name = "ttySC";
1369#endif
1370        sci_driver.major = SCI_MAJOR;
1371        sci_driver.minor_start = SCI_MINOR_START;
1372        sci_driver.num = SCI_NPORTS;
1373        sci_driver.type = TTY_DRIVER_TYPE_SERIAL;
1374        sci_driver.subtype = SERIAL_TYPE_NORMAL;
1375        sci_driver.init_termios = tty_std_termios;
1376        sci_driver.init_termios.c_cflag =
1377                B9600 | CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS;
1378        sci_driver.flags = TTY_DRIVER_REAL_RAW;
1379        sci_driver.refcount = &sci_refcount;
1380        sci_driver.table = sci_table;
1381        sci_driver.termios = sci_termios;
1382        sci_driver.termios_locked = sci_termios_locked;
1383
1384        sci_driver.open = sci_open;
1385        sci_driver.close = gs_close;
1386        sci_driver.write = gs_write;
1387        sci_driver.put_char = gs_put_char;
1388        sci_driver.flush_chars = gs_flush_chars;
1389        sci_driver.write_room = gs_write_room;
1390        sci_driver.chars_in_buffer = gs_chars_in_buffer;
1391        sci_driver.flush_buffer = gs_flush_buffer;
1392        sci_driver.ioctl = sci_ioctl;
1393        sci_driver.throttle = sci_throttle;
1394        sci_driver.unthrottle = sci_unthrottle;
1395        sci_driver.set_termios = gs_set_termios;
1396        sci_driver.stop = gs_stop;
1397        sci_driver.start = gs_start;
1398        sci_driver.hangup = gs_hangup;
1399#ifdef CONFIG_PROC_FS
1400        sci_driver.read_proc = sci_read_proc;
1401#endif
1402
1403        sci_callout_driver = sci_driver;
1404#ifdef CONFIG_DEVFS_FS
1405        sci_callout_driver.name = "cusc/%d";
1406#else
1407        sci_callout_driver.name = "cusc";
1408#endif
1409        sci_callout_driver.major = SCI_MAJOR+1;
1410        sci_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
1411        sci_callout_driver.read_proc = NULL;
1412
1413        if ((error = tty_register_driver(&sci_driver))) {
1414                printk(KERN_ERR "sci: Couldn't register SCI driver, error = %d\n",
1415                       error);
1416                return 1;
1417        }
1418        if ((error = tty_register_driver(&sci_callout_driver))) {
1419                tty_unregister_driver(&sci_driver);
1420                printk(KERN_ERR "sci: Couldn't register SCI callout driver, error = %d\n",
1421                       error);
1422                return 1;
1423        }
1424
1425        for (port = &sci_ports[0]; port < &sci_ports[SCI_NPORTS]; port++) {
1426                port->gs.callout_termios = sci_callout_driver.init_termios;
1427                port->gs.normal_termios = sci_driver.init_termios;
1428                port->gs.magic = SCI_MAGIC;
1429                port->gs.close_delay = HZ/2;
1430                port->gs.closing_wait = 30 * HZ;
1431                port->gs.rd = &sci_real_driver;
1432                init_waitqueue_head(&port->gs.open_wait);
1433                init_waitqueue_head(&port->gs.close_wait);
1434                port->old_cflag = 0;
1435                port->icount.cts = port->icount.dsr = 
1436                        port->icount.rng = port->icount.dcd = 0;
1437                port->icount.rx = port->icount.tx = 0;
1438                port->icount.frame = port->icount.parity = 0;
1439                port->icount.overrun = port->icount.brk = 0;
1440        }
1441
1442        return 0;
1443}
1444
1445static int sci_request_irq(struct sci_port *port)
1446{
1447        int i;
1448        void (*handlers[4])(int irq, void *ptr, struct pt_regs *regs) = {
1449                sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt,
1450                sci_br_interrupt,
1451        };
1452
1453        if(port->irqs[0] == port->irqs[1]){
1454                if (!port->irqs[0]){
1455                        printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n");
1456                        return -ENODEV;
1457                }
1458                if (request_irq(port->irqs[0], sci_mpxed_interrupt, SA_INTERRUPT,
1459                                "sci", port)) {
1460                        printk(KERN_ERR "sci: Cannot allocate irq.\n");
1461                        return -ENODEV;
1462                }
1463        }
1464        else{
1465                for (i=0; i<4; i++) {
1466                        if (!port->irqs[i]) continue;
1467                        if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
1468                                "sci", port)) {
1469                                printk(KERN_ERR "sci: Cannot allocate irq.\n");
1470                                return -ENODEV;
1471                        }
1472                }
1473        }
1474        return 0;
1475}
1476
1477static void sci_free_irq(struct sci_port *port)
1478{
1479        int i;
1480
1481        if(port->irqs[0] == port->irqs[1]){
1482                if(!port->irqs[0]){
1483                        printk("sci: sci_free_irq error\n");
1484                }else{
1485                        free_irq(port->irqs[0], port);
1486                }
1487        }else{
1488                for (i=0; i<4; i++) {
1489                        if (!port->irqs[i]) continue;
1490                        free_irq(port->irqs[i], port);
1491                }
1492        }
1493}
1494
1495static char banner[] __initdata =
1496        KERN_INFO "SuperH SCI(F) driver initialized\n";
1497
1498int __init sci_init(void)
1499{
1500        struct sci_port *port;
1501        int j;
1502
1503        printk("%s", banner);
1504
1505        for (j=0; j<SCI_NPORTS; j++) {
1506                port = &sci_ports[j];
1507                printk(KERN_INFO "ttySC%d at 0x%08x is a %s\n", j, port->base,
1508                       (port->type == PORT_SCI) ? "SCI" : "SCIF");
1509        }
1510
1511#if defined(CONFIG_SH_SECUREEDGE5410)
1512        init_timer(&sci_timer_struct);
1513        sci_timer_struct.function = sci_timer;
1514        sci_timer_struct.data = 0;
1515        sci_timer_struct.expires = jiffies + HZ/25;
1516        add_timer(&sci_timer_struct);
1517
1518        j = SECUREEDGE_READ_IOPORT();
1519        sci_dcdstatus[0] = !(j & 0x10);
1520        sci_dcdstatus[1] = !(j & 0x1);
1521#endif
1522
1523        sci_init_drivers();
1524
1525#ifdef CONFIG_SH_STANDARD_BIOS
1526        sh_bios_gdb_detach();
1527#endif
1528        return 0;               /* Return -EIO when not detected */
1529}
1530
1531module_init(sci_init);
1532
1533#ifdef MODULE
1534#undef func_enter
1535#undef func_exit
1536
1537void cleanup_module(void)
1538{
1539#if defined(CONFIG_SH_SECUREEDGE5410)
1540        del_timer(&sci_timer_struct);
1541#endif
1542        tty_unregister_driver(&sci_driver);
1543        tty_unregister_driver(&sci_callout_driver);
1544}
1545
1546#include "generic_serial.c"
1547#endif
1548
1549#ifdef CONFIG_SERIAL_CONSOLE
1550/*
1551 *      Print a string to the serial port trying not to disturb
1552 *      any possible real use of the port...
1553 */
1554static void serial_console_write(struct console *co, const char *s,
1555                                 unsigned count)
1556{
1557        put_string(sercons_port, s, count);
1558}
1559
1560static kdev_t serial_console_device(struct console *c)
1561{
1562        return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index);
1563}
1564
1565/*
1566 *      Setup initial baud/bits/parity. We do two things here:
1567 *      - construct a cflag setting for the first rs_open()
1568 *      - initialize the serial port
1569 *      Return non-zero if we didn't find a serial port.
1570 */
1571static int __init serial_console_setup(struct console *co, char *options)
1572{
1573        int     baud = 9600;
1574        int     bits = 8;
1575        int     parity = 'n';
1576        int     cflag = CREAD | HUPCL | CLOCAL;
1577        char    *s;
1578
1579        sercons_port = &sci_ports[co->index];
1580
1581#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
1582        sercons_port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
1583        if (!sercons_port->base)
1584                return -EINVAL;
1585#endif
1586
1587        if (options) {
1588                baud = simple_strtoul(options, NULL, 10);
1589                s = options;
1590                while(*s >= '0' && *s <= '9')
1591                        s++;
1592                if (*s) parity = *s++;
1593                if (*s) bits   = *s - '0';
1594        }
1595
1596        /*
1597         *      Now construct a cflag setting.
1598         */
1599        switch (baud) {
1600                case 19200:
1601                        cflag |= B19200;
1602                        break;
1603                case 38400:
1604                        cflag |= B38400;
1605                        break;
1606                case 57600:
1607                        cflag |= B57600;
1608                        break;
1609                case 115200:
1610                        cflag |= B115200;
1611                        break;
1612                case 230400:
1613                        cflag |= B230400;
1614                        break;
1615                case 9600:
1616                default:
1617                        cflag |= B9600;
1618                        baud = 9600;
1619                        break;
1620        }
1621        switch (bits) {
1622                case 7:
1623                        cflag |= CS7;
1624                        break;
1625                default:
1626                case 8:
1627                        cflag |= CS8;
1628                        break;
1629        }
1630        switch (parity) {
1631                case 'o': case 'O':
1632                        cflag |= PARODD;
1633                        break;
1634                case 'e': case 'E':
1635                        cflag |= PARENB;
1636                        break;
1637        }
1638
1639#ifdef CONFIG_SH_KGDB
1640        if (kgdb_in_gdb_mode && sercons_port == kgdb_sci_port) {
1641                co->cflag = kgdb_cflag;
1642                sercons_baud = kgdb_baud;
1643                sercons_port->old_cflag = cflag;
1644        }
1645        else
1646#endif /* CONFIG_SH_KGDB */
1647        {
1648                co->cflag = cflag;
1649                sercons_baud = baud;
1650
1651                sci_set_termios_cflag(sercons_port, cflag, baud);
1652                sercons_port->old_cflag = cflag;
1653        }
1654
1655        return 0;
1656}
1657
1658static struct console sercons = {
1659        name:           "ttySC",
1660        write:          serial_console_write,
1661        device:         serial_console_device,
1662        setup:          serial_console_setup,
1663        flags:          CON_PRINTBUFFER,
1664        index:          -1,
1665};
1666
1667/*
1668 *      Register console.
1669 */
1670
1671#ifdef CONFIG_SH_EARLY_PRINTK
1672extern void sh_console_unregister (void);
1673#endif
1674
1675void __init sci_console_init(void)
1676{
1677        register_console(&sercons);
1678#ifdef CONFIG_SH_EARLY_PRINTK
1679        /* Now that the real console is available, unregister the one we
1680         * used while first booting.
1681         */
1682        sh_console_unregister();
1683#endif
1684}
1685#endif /* CONFIG_SERIAL_CONSOLE */
1686
1687
1688#ifdef CONFIG_SH_KGDB
1689
1690/* Initialise the KGDB serial port */
1691int kgdb_sci_setup(void)
1692{
1693        int cflag = CREAD | HUPCL | CLOCAL;
1694
1695        if ((kgdb_portnum < 0) || (kgdb_portnum >= SCI_NPORTS))
1696                return -1;
1697
1698        kgdb_sci_port = &sci_ports[kgdb_portnum];
1699
1700        switch (kgdb_baud) {
1701        case 115200:
1702                cflag |= B115200;
1703                break;
1704        case 57600:
1705                cflag |= B57600;
1706                break;
1707        case 38400:
1708                cflag |= B38400;
1709                break;
1710        case 19200:
1711                cflag |= B19200;
1712                break;
1713        case 9600:
1714        default:
1715                cflag |= B9600;
1716                kgdb_baud = 9600;
1717                break;
1718        }
1719
1720        switch (kgdb_bits) {
1721        case '7':
1722                cflag |= CS7;
1723                break;
1724        default:
1725        case '8':
1726                cflag |= CS8;
1727                break;
1728        }
1729
1730        switch (kgdb_parity) {
1731        case 'O':
1732                cflag |= PARODD;
1733                break;
1734        case 'E':
1735                cflag |= PARENB;
1736                break;
1737        }
1738
1739        kgdb_cflag = cflag;
1740        sci_set_termios_cflag(kgdb_sci_port, kgdb_cflag, kgdb_baud);
1741
1742        /* Set up the interrupt for BREAK from GDB */
1743        /* Commented out for now since it may not be possible yet...
1744           request_irq(kgdb_sci_port->irqs[0], kgdb_break_interrupt,
1745                       SA_INTERRUPT, "sci", kgdb_sci_port);
1746           sci_enable_rx_interrupts(kgdb_sci_port);
1747        */
1748
1749        /* Setup complete: initialize function pointers */
1750        kgdb_getchar = kgdb_sci_getchar;
1751        kgdb_putchar = kgdb_sci_putchar;
1752
1753        return 0;
1754}
1755
1756#ifdef CONFIG_SH_KGDB_CONSOLE
1757
1758/* Create a console device */
1759static kdev_t kgdb_console_device(struct console *c)
1760{
1761        return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index);
1762}
1763
1764/* Set up the KGDB console */
1765static int __init kgdb_console_setup(struct console *co, char *options)
1766{
1767        /* NB we ignore 'options' because we've already done the setup */
1768        co->cflag = kgdb_cflag;
1769
1770        return 0;
1771}
1772
1773/* Register the KGDB console so we get messages (d'oh!) */
1774void __init kgdb_console_init(void)
1775{
1776        register_console(&kgdbcons);
1777}
1778
1779/* The console structure for KGDB */
1780static struct console kgdbcons = {
1781        name:"ttySC",
1782        write:kgdb_console_write,
1783        device:kgdb_console_device,
1784        wait_key:serial_console_wait_key,
1785        setup:kgdb_console_setup,
1786        flags:CON_PRINTBUFFER | CON_ENABLED,
1787        index:-1,
1788};
1789
1790#endif /* CONFIG_SH_KGDB_CONSOLE */
1791
1792#endif /* CONFIG_SH_KGDB */
1793
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.