linux/drivers/ipack/devices/ipoctal.c
<<
>>
Prefs
   1/**
   2 * ipoctal.c
   3 *
   4 * driver for the GE IP-OCTAL boards
   5 *
   6 * Copyright (C) 2009-2012 CERN (www.cern.ch)
   7 * Author: Nicolas Serafini, EIC2 SA
   8 * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify it
  11 * under the terms of the GNU General Public License as published by the Free
  12 * Software Foundation; version 2 of the License.
  13 */
  14
  15#include <linux/device.h>
  16#include <linux/module.h>
  17#include <linux/interrupt.h>
  18#include <linux/sched.h>
  19#include <linux/tty.h>
  20#include <linux/serial.h>
  21#include <linux/tty_flip.h>
  22#include <linux/slab.h>
  23#include <linux/io.h>
  24#include <linux/ipack.h>
  25#include "ipoctal.h"
  26#include "scc2698.h"
  27
  28#define IP_OCTAL_ID_SPACE_VECTOR    0x41
  29#define IP_OCTAL_NB_BLOCKS          4
  30
  31static const struct tty_operations ipoctal_fops;
  32
  33struct ipoctal_channel {
  34        struct ipoctal_stats            stats;
  35        unsigned int                    nb_bytes;
  36        wait_queue_head_t               queue;
  37        spinlock_t                      lock;
  38        unsigned int                    pointer_read;
  39        unsigned int                    pointer_write;
  40        struct tty_port                 tty_port;
  41        union scc2698_channel __iomem   *regs;
  42        union scc2698_block __iomem     *block_regs;
  43        unsigned int                    board_id;
  44        u8                              isr_rx_rdy_mask;
  45        u8                              isr_tx_rdy_mask;
  46        unsigned int                    rx_enable;
  47};
  48
  49struct ipoctal {
  50        struct ipack_device             *dev;
  51        unsigned int                    board_id;
  52        struct ipoctal_channel          channel[NR_CHANNELS];
  53        struct tty_driver               *tty_drv;
  54        u8 __iomem                      *mem8_space;
  55        u8 __iomem                      *int_space;
  56};
  57
  58static inline struct ipoctal *chan_to_ipoctal(struct ipoctal_channel *chan,
  59                                              unsigned int index)
  60{
  61        return container_of(chan, struct ipoctal, channel[index]);
  62}
  63
  64static void ipoctal_reset_channel(struct ipoctal_channel *channel)
  65{
  66        iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr);
  67        channel->rx_enable = 0;
  68        iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr);
  69        iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr);
  70        iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
  71        iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr);
  72}
  73
  74static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty)
  75{
  76        struct ipoctal_channel *channel;
  77
  78        channel = dev_get_drvdata(tty->dev);
  79
  80        /*
  81         * Enable RX. TX will be enabled when
  82         * there is something to send
  83         */
  84        iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
  85        channel->rx_enable = 1;
  86        return 0;
  87}
  88
  89static int ipoctal_open(struct tty_struct *tty, struct file *file)
  90{
  91        struct ipoctal_channel *channel = dev_get_drvdata(tty->dev);
  92        struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index);
  93        int err;
  94
  95        tty->driver_data = channel;
  96
  97        if (!ipack_get_carrier(ipoctal->dev))
  98                return -EBUSY;
  99
 100        err = tty_port_open(&channel->tty_port, tty, file);
 101        if (err)
 102                ipack_put_carrier(ipoctal->dev);
 103
 104        return err;
 105}
 106
 107static void ipoctal_reset_stats(struct ipoctal_stats *stats)
 108{
 109        stats->tx = 0;
 110        stats->rx = 0;
 111        stats->rcv_break = 0;
 112        stats->framing_err = 0;
 113        stats->overrun_err = 0;
 114        stats->parity_err = 0;
 115}
 116
 117static void ipoctal_free_channel(struct ipoctal_channel *channel)
 118{
 119        ipoctal_reset_stats(&channel->stats);
 120        channel->pointer_read = 0;
 121        channel->pointer_write = 0;
 122        channel->nb_bytes = 0;
 123}
 124
 125static void ipoctal_close(struct tty_struct *tty, struct file *filp)
 126{
 127        struct ipoctal_channel *channel = tty->driver_data;
 128
 129        tty_port_close(&channel->tty_port, tty, filp);
 130        ipoctal_free_channel(channel);
 131}
 132
 133static int ipoctal_get_icount(struct tty_struct *tty,
 134                              struct serial_icounter_struct *icount)
 135{
 136        struct ipoctal_channel *channel = tty->driver_data;
 137
 138        icount->cts = 0;
 139        icount->dsr = 0;
 140        icount->rng = 0;
 141        icount->dcd = 0;
 142        icount->rx = channel->stats.rx;
 143        icount->tx = channel->stats.tx;
 144        icount->frame = channel->stats.framing_err;
 145        icount->parity = channel->stats.parity_err;
 146        icount->brk = channel->stats.rcv_break;
 147        return 0;
 148}
 149
 150static void ipoctal_irq_rx(struct ipoctal_channel *channel, u8 sr)
 151{
 152        struct tty_port *port = &channel->tty_port;
 153        unsigned char value;
 154        unsigned char flag;
 155        u8 isr;
 156
 157        do {
 158                value = ioread8(&channel->regs->r.rhr);
 159                flag = TTY_NORMAL;
 160                /* Error: count statistics */
 161                if (sr & SR_ERROR) {
 162                        iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
 163
 164                        if (sr & SR_OVERRUN_ERROR) {
 165                                channel->stats.overrun_err++;
 166                                /* Overrun doesn't affect the current character*/
 167                                tty_insert_flip_char(port, 0, TTY_OVERRUN);
 168                        }
 169                        if (sr & SR_PARITY_ERROR) {
 170                                channel->stats.parity_err++;
 171                                flag = TTY_PARITY;
 172                        }
 173                        if (sr & SR_FRAMING_ERROR) {
 174                                channel->stats.framing_err++;
 175                                flag = TTY_FRAME;
 176                        }
 177                        if (sr & SR_RECEIVED_BREAK) {
 178                                channel->stats.rcv_break++;
 179                                flag = TTY_BREAK;
 180                        }
 181                }
 182                tty_insert_flip_char(port, value, flag);
 183
 184                /* Check if there are more characters in RX FIFO
 185                 * If there are more, the isr register for this channel
 186                 * has enabled the RxRDY|FFULL bit.
 187                 */
 188                isr = ioread8(&channel->block_regs->r.isr);
 189                sr = ioread8(&channel->regs->r.sr);
 190        } while (isr & channel->isr_rx_rdy_mask);
 191
 192        tty_flip_buffer_push(port);
 193}
 194
 195static void ipoctal_irq_tx(struct ipoctal_channel *channel)
 196{
 197        unsigned char value;
 198        unsigned int *pointer_write = &channel->pointer_write;
 199
 200        if (channel->nb_bytes == 0)
 201                return;
 202
 203        spin_lock(&channel->lock);
 204        value = channel->tty_port.xmit_buf[*pointer_write];
 205        iowrite8(value, &channel->regs->w.thr);
 206        channel->stats.tx++;
 207        (*pointer_write)++;
 208        *pointer_write = *pointer_write % PAGE_SIZE;
 209        channel->nb_bytes--;
 210        spin_unlock(&channel->lock);
 211}
 212
 213static void ipoctal_irq_channel(struct ipoctal_channel *channel)
 214{
 215        u8 isr, sr;
 216
 217        /* The HW is organized in pair of channels.  See which register we need
 218         * to read from */
 219        isr = ioread8(&channel->block_regs->r.isr);
 220        sr = ioread8(&channel->regs->r.sr);
 221
 222        if (isr & (IMR_DELTA_BREAK_A | IMR_DELTA_BREAK_B))
 223                iowrite8(CR_CMD_RESET_BREAK_CHANGE, &channel->regs->w.cr);
 224
 225        if ((sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) {
 226                iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
 227                /* In case of RS-485, change from TX to RX when finishing TX.
 228                 * Half-duplex. */
 229                if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
 230                        iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr);
 231                        iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
 232                        channel->rx_enable = 1;
 233                }
 234        }
 235
 236        /* RX data */
 237        if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY))
 238                ipoctal_irq_rx(channel, sr);
 239
 240        /* TX of each character */
 241        if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY))
 242                ipoctal_irq_tx(channel);
 243}
 244
 245static irqreturn_t ipoctal_irq_handler(void *arg)
 246{
 247        unsigned int i;
 248        struct ipoctal *ipoctal = (struct ipoctal *) arg;
 249
 250        /* Clear the IPack device interrupt */
 251        readw(ipoctal->int_space + ACK_INT_REQ0);
 252        readw(ipoctal->int_space + ACK_INT_REQ1);
 253
 254        /* Check all channels */
 255        for (i = 0; i < NR_CHANNELS; i++)
 256                ipoctal_irq_channel(&ipoctal->channel[i]);
 257
 258        return IRQ_HANDLED;
 259}
 260
 261static const struct tty_port_operations ipoctal_tty_port_ops = {
 262        .dtr_rts = NULL,
 263        .activate = ipoctal_port_activate,
 264};
 265
 266static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 267                             unsigned int slot)
 268{
 269        int res;
 270        int i;
 271        struct tty_driver *tty;
 272        char name[20];
 273        struct ipoctal_channel *channel;
 274        struct ipack_region *region;
 275        void __iomem *addr;
 276        union scc2698_channel __iomem *chan_regs;
 277        union scc2698_block __iomem *block_regs;
 278
 279        ipoctal->board_id = ipoctal->dev->id_device;
 280
 281        region = &ipoctal->dev->region[IPACK_IO_SPACE];
 282        addr = devm_ioremap_nocache(&ipoctal->dev->dev,
 283                                    region->start, region->size);
 284        if (!addr) {
 285                dev_err(&ipoctal->dev->dev,
 286                        "Unable to map slot [%d:%d] IO space!\n",
 287                        bus_nr, slot);
 288                return -EADDRNOTAVAIL;
 289        }
 290        /* Save the virtual address to access the registers easily */
 291        chan_regs =
 292                (union scc2698_channel __iomem *) addr;
 293        block_regs =
 294                (union scc2698_block __iomem *) addr;
 295
 296        region = &ipoctal->dev->region[IPACK_INT_SPACE];
 297        ipoctal->int_space =
 298                devm_ioremap_nocache(&ipoctal->dev->dev,
 299                                     region->start, region->size);
 300        if (!ipoctal->int_space) {
 301                dev_err(&ipoctal->dev->dev,
 302                        "Unable to map slot [%d:%d] INT space!\n",
 303                        bus_nr, slot);
 304                return -EADDRNOTAVAIL;
 305        }
 306
 307        region = &ipoctal->dev->region[IPACK_MEM8_SPACE];
 308        ipoctal->mem8_space =
 309                devm_ioremap_nocache(&ipoctal->dev->dev,
 310                                     region->start, 0x8000);
 311        if (!ipoctal->mem8_space) {
 312                dev_err(&ipoctal->dev->dev,
 313                        "Unable to map slot [%d:%d] MEM8 space!\n",
 314                        bus_nr, slot);
 315                return -EADDRNOTAVAIL;
 316        }
 317
 318
 319        /* Disable RX and TX before touching anything */
 320        for (i = 0; i < NR_CHANNELS ; i++) {
 321                struct ipoctal_channel *channel = &ipoctal->channel[i];
 322                channel->regs = chan_regs + i;
 323                channel->block_regs = block_regs + (i >> 1);
 324                channel->board_id = ipoctal->board_id;
 325                if (i & 1) {
 326                        channel->isr_tx_rdy_mask = ISR_TxRDY_B;
 327                        channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_B;
 328                } else {
 329                        channel->isr_tx_rdy_mask = ISR_TxRDY_A;
 330                        channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A;
 331                }
 332
 333                ipoctal_reset_channel(channel);
 334                iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY,
 335                         &channel->regs->w.mr); /* mr1 */
 336                iowrite8(0, &channel->regs->w.mr); /* mr2 */
 337                iowrite8(TX_CLK_9600  | RX_CLK_9600, &channel->regs->w.csr);
 338        }
 339
 340        for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) {
 341                iowrite8(ACR_BRG_SET2, &block_regs[i].w.acr);
 342                iowrite8(OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN,
 343                         &block_regs[i].w.opcr);
 344                iowrite8(IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A |
 345                         IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B,
 346                         &block_regs[i].w.imr);
 347        }
 348
 349        /* Dummy write */
 350        iowrite8(1, ipoctal->mem8_space + 1);
 351
 352        /* Register the TTY device */
 353
 354        /* Each IP-OCTAL channel is a TTY port */
 355        tty = alloc_tty_driver(NR_CHANNELS);
 356
 357        if (!tty)
 358                return -ENOMEM;
 359
 360        /* Fill struct tty_driver with ipoctal data */
 361        tty->owner = THIS_MODULE;
 362        tty->driver_name = KBUILD_MODNAME;
 363        sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot);
 364        tty->name = name;
 365        tty->major = 0;
 366
 367        tty->minor_start = 0;
 368        tty->type = TTY_DRIVER_TYPE_SERIAL;
 369        tty->subtype = SERIAL_TYPE_NORMAL;
 370        tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 371        tty->init_termios = tty_std_termios;
 372        tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 373        tty->init_termios.c_ispeed = 9600;
 374        tty->init_termios.c_ospeed = 9600;
 375
 376        tty_set_operations(tty, &ipoctal_fops);
 377        res = tty_register_driver(tty);
 378        if (res) {
 379                dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n");
 380                put_tty_driver(tty);
 381                return res;
 382        }
 383
 384        /* Save struct tty_driver for use it when uninstalling the device */
 385        ipoctal->tty_drv = tty;
 386
 387        for (i = 0; i < NR_CHANNELS; i++) {
 388                struct device *tty_dev;
 389
 390                channel = &ipoctal->channel[i];
 391                tty_port_init(&channel->tty_port);
 392                tty_port_alloc_xmit_buf(&channel->tty_port);
 393                channel->tty_port.ops = &ipoctal_tty_port_ops;
 394
 395                ipoctal_reset_stats(&channel->stats);
 396                channel->nb_bytes = 0;
 397                spin_lock_init(&channel->lock);
 398                channel->pointer_read = 0;
 399                channel->pointer_write = 0;
 400                tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL);
 401                if (IS_ERR(tty_dev)) {
 402                        dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
 403                        tty_port_destroy(&channel->tty_port);
 404                        continue;
 405                }
 406                dev_set_drvdata(tty_dev, channel);
 407        }
 408
 409        /*
 410         * IP-OCTAL has different addresses to copy its IRQ vector.
 411         * Depending of the carrier these addresses are accesible or not.
 412         * More info in the datasheet.
 413         */
 414        ipoctal->dev->bus->ops->request_irq(ipoctal->dev,
 415                                       ipoctal_irq_handler, ipoctal);
 416
 417        return 0;
 418}
 419
 420static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
 421                                            const unsigned char *buf,
 422                                            int count)
 423{
 424        unsigned long flags;
 425        int i;
 426        unsigned int *pointer_read = &channel->pointer_read;
 427
 428        /* Copy the bytes from the user buffer to the internal one */
 429        for (i = 0; i < count; i++) {
 430                if (i <= (PAGE_SIZE - channel->nb_bytes)) {
 431                        spin_lock_irqsave(&channel->lock, flags);
 432                        channel->tty_port.xmit_buf[*pointer_read] = buf[i];
 433                        *pointer_read = (*pointer_read + 1) % PAGE_SIZE;
 434                        channel->nb_bytes++;
 435                        spin_unlock_irqrestore(&channel->lock, flags);
 436                } else {
 437                        break;
 438                }
 439        }
 440        return i;
 441}
 442
 443static int ipoctal_write_tty(struct tty_struct *tty,
 444                             const unsigned char *buf, int count)
 445{
 446        struct ipoctal_channel *channel = tty->driver_data;
 447        unsigned int char_copied;
 448
 449        char_copied = ipoctal_copy_write_buffer(channel, buf, count);
 450
 451        /* As the IP-OCTAL 485 only supports half duplex, do it manually */
 452        if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) {
 453                iowrite8(CR_DISABLE_RX, &channel->regs->w.cr);
 454                channel->rx_enable = 0;
 455                iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr);
 456        }
 457
 458        /*
 459         * Send a packet and then disable TX to avoid failure after several send
 460         * operations
 461         */
 462        iowrite8(CR_ENABLE_TX, &channel->regs->w.cr);
 463        return char_copied;
 464}
 465
 466static int ipoctal_write_room(struct tty_struct *tty)
 467{
 468        struct ipoctal_channel *channel = tty->driver_data;
 469
 470        return PAGE_SIZE - channel->nb_bytes;
 471}
 472
 473static int ipoctal_chars_in_buffer(struct tty_struct *tty)
 474{
 475        struct ipoctal_channel *channel = tty->driver_data;
 476
 477        return channel->nb_bytes;
 478}
 479
 480static void ipoctal_set_termios(struct tty_struct *tty,
 481                                struct ktermios *old_termios)
 482{
 483        unsigned int cflag;
 484        unsigned char mr1 = 0;
 485        unsigned char mr2 = 0;
 486        unsigned char csr = 0;
 487        struct ipoctal_channel *channel = tty->driver_data;
 488        speed_t baud;
 489
 490        cflag = tty->termios.c_cflag;
 491
 492        /* Disable and reset everything before change the setup */
 493        ipoctal_reset_channel(channel);
 494
 495        /* Set Bits per chars */
 496        switch (cflag & CSIZE) {
 497        case CS6:
 498                mr1 |= MR1_CHRL_6_BITS;
 499                break;
 500        case CS7:
 501                mr1 |= MR1_CHRL_7_BITS;
 502                break;
 503        case CS8:
 504        default:
 505                mr1 |= MR1_CHRL_8_BITS;
 506                /* By default, select CS8 */
 507                tty->termios.c_cflag = (cflag & ~CSIZE) | CS8;
 508                break;
 509        }
 510
 511        /* Set Parity */
 512        if (cflag & PARENB)
 513                if (cflag & PARODD)
 514                        mr1 |= MR1_PARITY_ON | MR1_PARITY_ODD;
 515                else
 516                        mr1 |= MR1_PARITY_ON | MR1_PARITY_EVEN;
 517        else
 518                mr1 |= MR1_PARITY_OFF;
 519
 520        /* Mark or space parity is not supported */
 521        tty->termios.c_cflag &= ~CMSPAR;
 522
 523        /* Set stop bits */
 524        if (cflag & CSTOPB)
 525                mr2 |= MR2_STOP_BITS_LENGTH_2;
 526        else
 527                mr2 |= MR2_STOP_BITS_LENGTH_1;
 528
 529        /* Set the flow control */
 530        switch (channel->board_id) {
 531        case IPACK1_DEVICE_ID_SBS_OCTAL_232:
 532                if (cflag & CRTSCTS) {
 533                        mr1 |= MR1_RxRTS_CONTROL_ON;
 534                        mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON;
 535                } else {
 536                        mr1 |= MR1_RxRTS_CONTROL_OFF;
 537                        mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
 538                }
 539                break;
 540        case IPACK1_DEVICE_ID_SBS_OCTAL_422:
 541                mr1 |= MR1_RxRTS_CONTROL_OFF;
 542                mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF;
 543                break;
 544        case IPACK1_DEVICE_ID_SBS_OCTAL_485:
 545                mr1 |= MR1_RxRTS_CONTROL_OFF;
 546                mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF;
 547                break;
 548        default:
 549                return;
 550                break;
 551        }
 552
 553        baud = tty_get_baud_rate(tty);
 554        tty_termios_encode_baud_rate(&tty->termios, baud, baud);
 555
 556        /* Set baud rate */
 557        switch (baud) {
 558        case 75:
 559                csr |= TX_CLK_75 | RX_CLK_75;
 560                break;
 561        case 110:
 562                csr |= TX_CLK_110 | RX_CLK_110;
 563                break;
 564        case 150:
 565                csr |= TX_CLK_150 | RX_CLK_150;
 566                break;
 567        case 300:
 568                csr |= TX_CLK_300 | RX_CLK_300;
 569                break;
 570        case 600:
 571                csr |= TX_CLK_600 | RX_CLK_600;
 572                break;
 573        case 1200:
 574                csr |= TX_CLK_1200 | RX_CLK_1200;
 575                break;
 576        case 1800:
 577                csr |= TX_CLK_1800 | RX_CLK_1800;
 578                break;
 579        case 2000:
 580                csr |= TX_CLK_2000 | RX_CLK_2000;
 581                break;
 582        case 2400:
 583                csr |= TX_CLK_2400 | RX_CLK_2400;
 584                break;
 585        case 4800:
 586                csr |= TX_CLK_4800  | RX_CLK_4800;
 587                break;
 588        case 9600:
 589                csr |= TX_CLK_9600  | RX_CLK_9600;
 590                break;
 591        case 19200:
 592                csr |= TX_CLK_19200 | RX_CLK_19200;
 593                break;
 594        case 38400:
 595        default:
 596                csr |= TX_CLK_38400 | RX_CLK_38400;
 597                /* In case of default, we establish 38400 bps */
 598                tty_termios_encode_baud_rate(&tty->termios, 38400, 38400);
 599                break;
 600        }
 601
 602        mr1 |= MR1_ERROR_CHAR;
 603        mr1 |= MR1_RxINT_RxRDY;
 604
 605        /* Write the control registers */
 606        iowrite8(mr1, &channel->regs->w.mr);
 607        iowrite8(mr2, &channel->regs->w.mr);
 608        iowrite8(csr, &channel->regs->w.csr);
 609
 610        /* Enable again the RX, if it was before */
 611        if (channel->rx_enable)
 612                iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
 613}
 614
 615static void ipoctal_hangup(struct tty_struct *tty)
 616{
 617        unsigned long flags;
 618        struct ipoctal_channel *channel = tty->driver_data;
 619
 620        if (channel == NULL)
 621                return;
 622
 623        spin_lock_irqsave(&channel->lock, flags);
 624        channel->nb_bytes = 0;
 625        channel->pointer_read = 0;
 626        channel->pointer_write = 0;
 627        spin_unlock_irqrestore(&channel->lock, flags);
 628
 629        tty_port_hangup(&channel->tty_port);
 630
 631        ipoctal_reset_channel(channel);
 632        tty_port_set_initialized(&channel->tty_port, 0);
 633        wake_up_interruptible(&channel->tty_port.open_wait);
 634}
 635
 636static void ipoctal_shutdown(struct tty_struct *tty)
 637{
 638        struct ipoctal_channel *channel = tty->driver_data;
 639
 640        if (channel == NULL)
 641                return;
 642
 643        ipoctal_reset_channel(channel);
 644        tty_port_set_initialized(&channel->tty_port, 0);
 645}
 646
 647static void ipoctal_cleanup(struct tty_struct *tty)
 648{
 649        struct ipoctal_channel *channel = tty->driver_data;
 650        struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index);
 651
 652        /* release the carrier driver */
 653        ipack_put_carrier(ipoctal->dev);
 654}
 655
 656static const struct tty_operations ipoctal_fops = {
 657        .ioctl =                NULL,
 658        .open =                 ipoctal_open,
 659        .close =                ipoctal_close,
 660        .write =                ipoctal_write_tty,
 661        .set_termios =          ipoctal_set_termios,
 662        .write_room =           ipoctal_write_room,
 663        .chars_in_buffer =      ipoctal_chars_in_buffer,
 664        .get_icount =           ipoctal_get_icount,
 665        .hangup =               ipoctal_hangup,
 666        .shutdown =             ipoctal_shutdown,
 667        .cleanup =              ipoctal_cleanup,
 668};
 669
 670static int ipoctal_probe(struct ipack_device *dev)
 671{
 672        int res;
 673        struct ipoctal *ipoctal;
 674
 675        ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL);
 676        if (ipoctal == NULL)
 677                return -ENOMEM;
 678
 679        ipoctal->dev = dev;
 680        res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot);
 681        if (res)
 682                goto out_uninst;
 683
 684        dev_set_drvdata(&dev->dev, ipoctal);
 685        return 0;
 686
 687out_uninst:
 688        kfree(ipoctal);
 689        return res;
 690}
 691
 692static void __ipoctal_remove(struct ipoctal *ipoctal)
 693{
 694        int i;
 695
 696        ipoctal->dev->bus->ops->free_irq(ipoctal->dev);
 697
 698        for (i = 0; i < NR_CHANNELS; i++) {
 699                struct ipoctal_channel *channel = &ipoctal->channel[i];
 700                tty_unregister_device(ipoctal->tty_drv, i);
 701                tty_port_free_xmit_buf(&channel->tty_port);
 702                tty_port_destroy(&channel->tty_port);
 703        }
 704
 705        tty_unregister_driver(ipoctal->tty_drv);
 706        put_tty_driver(ipoctal->tty_drv);
 707        kfree(ipoctal);
 708}
 709
 710static void ipoctal_remove(struct ipack_device *idev)
 711{
 712        __ipoctal_remove(dev_get_drvdata(&idev->dev));
 713}
 714
 715static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = {
 716        { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
 717                        IPACK1_DEVICE_ID_SBS_OCTAL_232) },
 718        { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
 719                        IPACK1_DEVICE_ID_SBS_OCTAL_422) },
 720        { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS,
 721                        IPACK1_DEVICE_ID_SBS_OCTAL_485) },
 722        { 0, },
 723};
 724
 725MODULE_DEVICE_TABLE(ipack, ipoctal_ids);
 726
 727static const struct ipack_driver_ops ipoctal_drv_ops = {
 728        .probe  = ipoctal_probe,
 729        .remove = ipoctal_remove,
 730};
 731
 732static struct ipack_driver driver = {
 733        .ops      = &ipoctal_drv_ops,
 734        .id_table = ipoctal_ids,
 735};
 736
 737static int __init ipoctal_init(void)
 738{
 739        return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME);
 740}
 741
 742static void __exit ipoctal_exit(void)
 743{
 744        ipack_driver_unregister(&driver);
 745}
 746
 747MODULE_DESCRIPTION("IP-Octal 232, 422 and 485 device driver");
 748MODULE_LICENSE("GPL");
 749
 750module_init(ipoctal_init);
 751module_exit(ipoctal_exit);
 752