linux/drivers/serial/mux.c
<<
>>
Prefs
   1/*
   2** mux.c:
   3**      serial driver for the Mux console found in some PA-RISC servers.
   4**
   5**      (c) Copyright 2002 Ryan Bradetich
   6**      (c) Copyright 2002 Hewlett-Packard Company
   7**
   8** This program is free software; you can redistribute it and/or modify
   9** it under the terms of the GNU General Public License as published by
  10** the Free Software Foundation; either version 2 of the License, or
  11** (at your option) any later version.
  12**
  13** This Driver currently only supports the console (port 0) on the MUX.
  14** Additional work will be needed on this driver to enable the full
  15** functionality of the MUX.
  16**
  17*/
  18
  19#include <linux/module.h>
  20#include <linux/tty.h>
  21#include <linux/ioport.h>
  22#include <linux/init.h>
  23#include <linux/serial.h>
  24#include <linux/console.h>
  25#include <linux/slab.h>
  26#include <linux/delay.h> /* for udelay */
  27#include <linux/device.h>
  28#include <asm/io.h>
  29#include <asm/irq.h>
  30#include <asm/parisc-device.h>
  31
  32#ifdef CONFIG_MAGIC_SYSRQ
  33#include <linux/sysrq.h>
  34#define SUPPORT_SYSRQ
  35#endif
  36
  37#include <linux/serial_core.h>
  38
  39#define MUX_OFFSET 0x800
  40#define MUX_LINE_OFFSET 0x80
  41
  42#define MUX_FIFO_SIZE 255
  43#define MUX_POLL_DELAY (30 * HZ / 1000)
  44
  45#define IO_DATA_REG_OFFSET 0x3c
  46#define IO_DCOUNT_REG_OFFSET 0x40
  47
  48#define MUX_EOFIFO(status) ((status & 0xF000) == 0xF000)
  49#define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
  50#define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
  51
  52#define MUX_NR 256
  53static unsigned int port_cnt __read_mostly;
  54struct mux_port {
  55        struct uart_port port;
  56        int enabled;
  57};
  58static struct mux_port mux_ports[MUX_NR];
  59
  60static struct uart_driver mux_driver = {
  61        .owner = THIS_MODULE,
  62        .driver_name = "ttyB",
  63        .dev_name = "ttyB",
  64        .major = MUX_MAJOR,
  65        .minor = 0,
  66        .nr = MUX_NR,
  67};
  68
  69static struct timer_list mux_timer;
  70
  71#define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET)
  72#define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET)
  73
  74/**
  75 * get_mux_port_count - Get the number of available ports on the Mux.
  76 * @dev: The parisc device.
  77 *
  78 * This function is used to determine the number of ports the Mux
  79 * supports.  The IODC data reports the number of ports the Mux
  80 * can support, but there are cases where not all the Mux ports
  81 * are connected.  This function can override the IODC and
  82 * return the true port count.
  83 */
  84static int __init get_mux_port_count(struct parisc_device *dev)
  85{
  86        int status;
  87        u8 iodc_data[32];
  88        unsigned long bytecnt;
  89
  90        /* If this is the built-in Mux for the K-Class (Eole CAP/MUX),
  91         * we only need to allocate resources for 1 port since the
  92         * other 7 ports are not connected.
  93         */
  94        if(dev->id.hversion == 0x15)
  95                return 1;
  96
  97        status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32);
  98        BUG_ON(status != PDC_OK);
  99
 100        /* Return the number of ports specified in the iodc data. */
 101        return ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8;
 102}
 103
 104/**
 105 * mux_tx_empty - Check if the transmitter fifo is empty.
 106 * @port: Ptr to the uart_port.
 107 *
 108 * This function test if the transmitter fifo for the port
 109 * described by 'port' is empty.  If it is empty, this function
 110 * should return TIOCSER_TEMT, otherwise return 0.
 111 */
 112static unsigned int mux_tx_empty(struct uart_port *port)
 113{
 114        return UART_GET_FIFO_CNT(port) ? 0 : TIOCSER_TEMT;
 115} 
 116
 117/**
 118 * mux_set_mctrl - Set the current state of the modem control inputs.
 119 * @ports: Ptr to the uart_port.
 120 * @mctrl: Modem control bits.
 121 *
 122 * The Serial MUX does not support CTS, DCD or DSR so this function
 123 * is ignored.
 124 */
 125static void mux_set_mctrl(struct uart_port *port, unsigned int mctrl)
 126{
 127}
 128
 129/**
 130 * mux_get_mctrl - Returns the current state of modem control inputs.
 131 * @port: Ptr to the uart_port.
 132 *
 133 * The Serial MUX does not support CTS, DCD or DSR so these lines are
 134 * treated as permanently active.
 135 */
 136static unsigned int mux_get_mctrl(struct uart_port *port)
 137{ 
 138        return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
 139}
 140
 141/**
 142 * mux_stop_tx - Stop transmitting characters.
 143 * @port: Ptr to the uart_port.
 144 *
 145 * The Serial MUX does not support this function.
 146 */
 147static void mux_stop_tx(struct uart_port *port)
 148{
 149}
 150
 151/**
 152 * mux_start_tx - Start transmitting characters.
 153 * @port: Ptr to the uart_port.
 154 *
 155 * The Serial Mux does not support this function.
 156 */
 157static void mux_start_tx(struct uart_port *port)
 158{
 159}
 160
 161/**
 162 * mux_stop_rx - Stop receiving characters.
 163 * @port: Ptr to the uart_port.
 164 *
 165 * The Serial Mux does not support this function.
 166 */
 167static void mux_stop_rx(struct uart_port *port)
 168{
 169}
 170
 171/**
 172 * mux_enable_ms - Enable modum status interrupts.
 173 * @port: Ptr to the uart_port.
 174 *
 175 * The Serial Mux does not support this function.
 176 */
 177static void mux_enable_ms(struct uart_port *port)
 178{
 179}
 180
 181/**
 182 * mux_break_ctl - Control the transmitssion of a break signal.
 183 * @port: Ptr to the uart_port.
 184 * @break_state: Raise/Lower the break signal.
 185 *
 186 * The Serial Mux does not support this function.
 187 */
 188static void mux_break_ctl(struct uart_port *port, int break_state)
 189{
 190}
 191
 192/**
 193 * mux_write - Write chars to the mux fifo.
 194 * @port: Ptr to the uart_port.
 195 *
 196 * This function writes all the data from the uart buffer to
 197 * the mux fifo.
 198 */
 199static void mux_write(struct uart_port *port)
 200{
 201        int count;
 202        struct circ_buf *xmit = &port->info->xmit;
 203
 204        if(port->x_char) {
 205                UART_PUT_CHAR(port, port->x_char);
 206                port->icount.tx++;
 207                port->x_char = 0;
 208                return;
 209        }
 210
 211        if(uart_circ_empty(xmit) || uart_tx_stopped(port)) {
 212                mux_stop_tx(port);
 213                return;
 214        }
 215
 216        count = (port->fifosize) - UART_GET_FIFO_CNT(port);
 217        do {
 218                UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
 219                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 220                port->icount.tx++;
 221                if(uart_circ_empty(xmit))
 222                        break;
 223
 224        } while(--count > 0);
 225
 226        while(UART_GET_FIFO_CNT(port)) 
 227                udelay(1);
 228
 229        if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 230                uart_write_wakeup(port);
 231
 232        if (uart_circ_empty(xmit))
 233                mux_stop_tx(port);
 234}
 235
 236/**
 237 * mux_read - Read chars from the mux fifo.
 238 * @port: Ptr to the uart_port.
 239 *
 240 * This reads all available data from the mux's fifo and pushes
 241 * the data to the tty layer.
 242 */
 243static void mux_read(struct uart_port *port)
 244{
 245        int data;
 246        struct tty_struct *tty = port->info->port.tty;
 247        __u32 start_count = port->icount.rx;
 248
 249        while(1) {
 250                data = __raw_readl(port->membase + IO_DATA_REG_OFFSET);
 251
 252                if (MUX_STATUS(data))
 253                        continue;
 254
 255                if (MUX_EOFIFO(data))
 256                        break;
 257
 258                port->icount.rx++;
 259
 260                if (MUX_BREAK(data)) {
 261                        port->icount.brk++;
 262                        if(uart_handle_break(port))
 263                                continue;
 264                }
 265
 266                if (uart_handle_sysrq_char(port, data & 0xffu))
 267                        continue;
 268
 269                tty_insert_flip_char(tty, data & 0xFF, TTY_NORMAL);
 270        }
 271        
 272        if (start_count != port->icount.rx) {
 273                tty_flip_buffer_push(tty);
 274        }
 275}
 276
 277/**
 278 * mux_startup - Initialize the port.
 279 * @port: Ptr to the uart_port.
 280 *
 281 * Grab any resources needed for this port and start the
 282 * mux timer.
 283 */
 284static int mux_startup(struct uart_port *port)
 285{
 286        mux_ports[port->line].enabled = 1;
 287        return 0;
 288}
 289
 290/**
 291 * mux_shutdown - Disable the port.
 292 * @port: Ptr to the uart_port.
 293 *
 294 * Release any resources needed for the port.
 295 */
 296static void mux_shutdown(struct uart_port *port)
 297{
 298        mux_ports[port->line].enabled = 0;
 299}
 300
 301/**
 302 * mux_set_termios - Chane port parameters.
 303 * @port: Ptr to the uart_port.
 304 * @termios: new termios settings.
 305 * @old: old termios settings.
 306 *
 307 * The Serial Mux does not support this function.
 308 */
 309static void
 310mux_set_termios(struct uart_port *port, struct ktermios *termios,
 311                struct ktermios *old)
 312{
 313}
 314
 315/**
 316 * mux_type - Describe the port.
 317 * @port: Ptr to the uart_port.
 318 *
 319 * Return a pointer to a string constant describing the
 320 * specified port.
 321 */
 322static const char *mux_type(struct uart_port *port)
 323{
 324        return "Mux";
 325}
 326
 327/**
 328 * mux_release_port - Release memory and IO regions.
 329 * @port: Ptr to the uart_port.
 330 * 
 331 * Release any memory and IO region resources currently in use by
 332 * the port.
 333 */
 334static void mux_release_port(struct uart_port *port)
 335{
 336}
 337
 338/**
 339 * mux_request_port - Request memory and IO regions.
 340 * @port: Ptr to the uart_port.
 341 *
 342 * Request any memory and IO region resources required by the port.
 343 * If any fail, no resources should be registered when this function
 344 * returns, and it should return -EBUSY on failure.
 345 */
 346static int mux_request_port(struct uart_port *port)
 347{
 348        return 0;
 349}
 350
 351/**
 352 * mux_config_port - Perform port autoconfiguration.
 353 * @port: Ptr to the uart_port.
 354 * @type: Bitmask of required configurations.
 355 *
 356 * Perform any autoconfiguration steps for the port.  This function is
 357 * called if the UPF_BOOT_AUTOCONF flag is specified for the port.
 358 * [Note: This is required for now because of a bug in the Serial core.
 359 *  rmk has already submitted a patch to linus, should be available for
 360 *  2.5.47.]
 361 */
 362static void mux_config_port(struct uart_port *port, int type)
 363{
 364        port->type = PORT_MUX;
 365}
 366
 367/**
 368 * mux_verify_port - Verify the port information.
 369 * @port: Ptr to the uart_port.
 370 * @ser: Ptr to the serial information.
 371 *
 372 * Verify the new serial port information contained within serinfo is
 373 * suitable for this port type.
 374 */
 375static int mux_verify_port(struct uart_port *port, struct serial_struct *ser)
 376{
 377        if(port->membase == NULL)
 378                return -EINVAL;
 379
 380        return 0;
 381}
 382
 383/**
 384 * mux_drv_poll - Mux poll function.
 385 * @unused: Unused variable
 386 *
 387 * This function periodically polls the Serial MUX to check for new data.
 388 */
 389static void mux_poll(unsigned long unused)
 390{  
 391        int i;
 392
 393        for(i = 0; i < port_cnt; ++i) {
 394                if(!mux_ports[i].enabled)
 395                        continue;
 396
 397                mux_read(&mux_ports[i].port);
 398                mux_write(&mux_ports[i].port);
 399        }
 400
 401        mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
 402}
 403
 404
 405#ifdef CONFIG_SERIAL_MUX_CONSOLE
 406static void mux_console_write(struct console *co, const char *s, unsigned count)
 407{
 408        /* Wait until the FIFO drains. */
 409        while(UART_GET_FIFO_CNT(&mux_ports[0].port))
 410                udelay(1);
 411
 412        while(count--) {
 413                if(*s == '\n') {
 414                        UART_PUT_CHAR(&mux_ports[0].port, '\r');
 415                }
 416                UART_PUT_CHAR(&mux_ports[0].port, *s++);
 417        }
 418
 419}
 420
 421static int mux_console_setup(struct console *co, char *options)
 422{
 423        return 0;
 424}
 425
 426struct tty_driver *mux_console_device(struct console *co, int *index)
 427{
 428        *index = co->index;
 429        return mux_driver.tty_driver;
 430}
 431
 432static struct console mux_console = {
 433        .name =         "ttyB",
 434        .write =        mux_console_write,
 435        .device =       mux_console_device,
 436        .setup =        mux_console_setup,
 437        .flags =        CON_ENABLED | CON_PRINTBUFFER,
 438        .index =        0,
 439};
 440
 441#define MUX_CONSOLE     &mux_console
 442#else
 443#define MUX_CONSOLE     NULL
 444#endif
 445
 446static struct uart_ops mux_pops = {
 447        .tx_empty =             mux_tx_empty,
 448        .set_mctrl =            mux_set_mctrl,
 449        .get_mctrl =            mux_get_mctrl,
 450        .stop_tx =              mux_stop_tx,
 451        .start_tx =             mux_start_tx,
 452        .stop_rx =              mux_stop_rx,
 453        .enable_ms =            mux_enable_ms,
 454        .break_ctl =            mux_break_ctl,
 455        .startup =              mux_startup,
 456        .shutdown =             mux_shutdown,
 457        .set_termios =          mux_set_termios,
 458        .type =                 mux_type,
 459        .release_port =         mux_release_port,
 460        .request_port =         mux_request_port,
 461        .config_port =          mux_config_port,
 462        .verify_port =          mux_verify_port,
 463};
 464
 465/**
 466 * mux_probe - Determine if the Serial Mux should claim this device.
 467 * @dev: The parisc device.
 468 *
 469 * Deterimine if the Serial Mux should claim this chip (return 0)
 470 * or not (return 1).
 471 */
 472static int __init mux_probe(struct parisc_device *dev)
 473{
 474        int i, status;
 475
 476        int port_count = get_mux_port_count(dev);
 477        printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.6\n", port_count);
 478
 479        dev_set_drvdata(&dev->dev, (void *)(long)port_count);
 480        request_mem_region(dev->hpa.start + MUX_OFFSET,
 481                           port_count * MUX_LINE_OFFSET, "Mux");
 482
 483        if(!port_cnt) {
 484                mux_driver.cons = MUX_CONSOLE;
 485
 486                status = uart_register_driver(&mux_driver);
 487                if(status) {
 488                        printk(KERN_ERR "Serial mux: Unable to register driver.\n");
 489                        return 1;
 490                }
 491        }
 492
 493        for(i = 0; i < port_count; ++i, ++port_cnt) {
 494                struct uart_port *port = &mux_ports[port_cnt].port;
 495                port->iobase    = 0;
 496                port->mapbase   = dev->hpa.start + MUX_OFFSET +
 497                                                (i * MUX_LINE_OFFSET);
 498                port->membase   = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET);
 499                port->iotype    = UPIO_MEM;
 500                port->type      = PORT_MUX;
 501                port->irq       = NO_IRQ;
 502                port->uartclk   = 0;
 503                port->fifosize  = MUX_FIFO_SIZE;
 504                port->ops       = &mux_pops;
 505                port->flags     = UPF_BOOT_AUTOCONF;
 506                port->line      = port_cnt;
 507
 508                /* The port->timeout needs to match what is present in
 509                 * uart_wait_until_sent in serial_core.c.  Otherwise
 510                 * the time spent in msleep_interruptable will be very
 511                 * long, causing the appearance of a console hang.
 512                 */
 513                port->timeout   = HZ / 50;
 514                spin_lock_init(&port->lock);
 515
 516                status = uart_add_one_port(&mux_driver, port);
 517                BUG_ON(status);
 518        }
 519
 520        return 0;
 521}
 522
 523static int __devexit mux_remove(struct parisc_device *dev)
 524{
 525        int i, j;
 526        int port_count = (long)dev_get_drvdata(&dev->dev);
 527
 528        /* Find Port 0 for this card in the mux_ports list. */
 529        for(i = 0; i < port_cnt; ++i) {
 530                if(mux_ports[i].port.mapbase == dev->hpa.start + MUX_OFFSET)
 531                        break;
 532        }
 533        BUG_ON(i + port_count > port_cnt);
 534
 535        /* Release the resources associated with each port on the device. */
 536        for(j = 0; j < port_count; ++j, ++i) {
 537                struct uart_port *port = &mux_ports[i].port;
 538
 539                uart_remove_one_port(&mux_driver, port);
 540                if(port->membase)
 541                        iounmap(port->membase);
 542        }
 543
 544        release_mem_region(dev->hpa.start + MUX_OFFSET, port_count * MUX_LINE_OFFSET);
 545        return 0;
 546}
 547
 548/* Hack.  This idea was taken from the 8250_gsc.c on how to properly order
 549 * the serial port detection in the proper order.   The idea is we always
 550 * want the builtin mux to be detected before addin mux cards, so we
 551 * specifically probe for the builtin mux cards first.
 552 *
 553 * This table only contains the parisc_device_id of known builtin mux
 554 * devices.  All other mux cards will be detected by the generic mux_tbl.
 555 */
 556static struct parisc_device_id builtin_mux_tbl[] = {
 557        { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */
 558        { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */
 559        { 0, }
 560};
 561
 562static struct parisc_device_id mux_tbl[] = {
 563        { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D },
 564        { 0, }
 565};
 566
 567MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl);
 568MODULE_DEVICE_TABLE(parisc, mux_tbl);
 569
 570static struct parisc_driver builtin_serial_mux_driver = {
 571        .name =         "builtin_serial_mux",
 572        .id_table =     builtin_mux_tbl,
 573        .probe =        mux_probe,
 574        .remove =       __devexit_p(mux_remove),
 575};
 576
 577static struct parisc_driver serial_mux_driver = {
 578        .name =         "serial_mux",
 579        .id_table =     mux_tbl,
 580        .probe =        mux_probe,
 581        .remove =       __devexit_p(mux_remove),
 582};
 583
 584/**
 585 * mux_init - Serial MUX initialization procedure.
 586 *
 587 * Register the Serial MUX driver.
 588 */
 589static int __init mux_init(void)
 590{
 591        register_parisc_driver(&builtin_serial_mux_driver);
 592        register_parisc_driver(&serial_mux_driver);
 593
 594        if(port_cnt > 0) {
 595                /* Start the Mux timer */
 596                init_timer(&mux_timer);
 597                mux_timer.function = mux_poll;
 598                mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
 599
 600#ifdef CONFIG_SERIAL_MUX_CONSOLE
 601                register_console(&mux_console);
 602#endif
 603        }
 604
 605        return 0;
 606}
 607
 608/**
 609 * mux_exit - Serial MUX cleanup procedure.
 610 *
 611 * Unregister the Serial MUX driver from the tty layer.
 612 */
 613static void __exit mux_exit(void)
 614{
 615        /* Delete the Mux timer. */
 616        if(port_cnt > 0) {
 617                del_timer(&mux_timer);
 618#ifdef CONFIG_SERIAL_MUX_CONSOLE
 619                unregister_console(&mux_console);
 620#endif
 621        }
 622
 623        unregister_parisc_driver(&builtin_serial_mux_driver);
 624        unregister_parisc_driver(&serial_mux_driver);
 625        uart_unregister_driver(&mux_driver);
 626}
 627
 628module_init(mux_init);
 629module_exit(mux_exit);
 630
 631MODULE_AUTHOR("Ryan Bradetich");
 632MODULE_DESCRIPTION("Serial MUX driver");
 633MODULE_LICENSE("GPL");
 634MODULE_ALIAS_CHARDEV_MAJOR(MUX_MAJOR);
 635
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.