Staging: ipack/devices/ipoctal: Use KBUILD_MODNAME instead of hardcoded string.
[pandora-kernel.git] / drivers / staging / ipack / devices / ipoctal.c
index 56e810b..a0c1e76 100644 (file)
@@ -163,109 +163,115 @@ static int ipoctal_get_icount(struct tty_struct *tty,
        return 0;
 }
 
-static int ipoctal_irq_handler(void *arg)
+static void ipoctal_irq_rx(struct ipoctal_channel *channel,
+                          struct tty_struct *tty, u8 sr)
+{
+       unsigned char value = ioread8(&channel->regs->r.rhr);
+       unsigned char flag = TTY_NORMAL;
+
+       /* Error: count statistics */
+       if (sr & SR_ERROR) {
+               iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
+
+               if (sr & SR_OVERRUN_ERROR) {
+                       channel->stats.overrun_err++;
+                       /* Overrun doesn't affect the current character*/
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               }
+               if (sr & SR_PARITY_ERROR) {
+                       channel->stats.parity_err++;
+                       flag = TTY_PARITY;
+               }
+               if (sr & SR_FRAMING_ERROR) {
+                       channel->stats.framing_err++;
+                       flag = TTY_FRAME;
+               }
+               if (sr & SR_RECEIVED_BREAK) {
+                       channel->stats.rcv_break++;
+                       flag = TTY_BREAK;
+               }
+       }
+
+       tty_insert_flip_char(tty, value, flag);
+}
+
+static void ipoctal_irq_tx(struct ipoctal_channel *channel)
 {
-       unsigned int ichannel;
-       unsigned char isr;
-       unsigned char sr;
        unsigned char value;
-       unsigned char flag;
-       struct tty_struct *tty;
-       struct ipoctal *ipoctal = (struct ipoctal *) arg;
-       struct ipoctal_channel *channel;
+       unsigned int *pointer_write = &channel->pointer_write;
 
-       /* Check all channels */
-       for (ichannel = 0; ichannel < NR_CHANNELS; ichannel++) {
-               channel = &ipoctal->channel[ichannel];
-               /* If there is no client, skip the check */
-               if (!atomic_read(&channel->open))
-                       continue;
+       if (channel->nb_bytes <= 0) {
+               channel->nb_bytes = 0;
+               return;
+       }
 
-               tty = tty_port_tty_get(&channel->tty_port);
-               if (!tty)
-                       continue;
+       value = channel->tty_port.xmit_buf[*pointer_write];
+       iowrite8(value, &channel->regs->w.thr);
+       channel->stats.tx++;
+       channel->count_wr++;
+       (*pointer_write)++;
+       *pointer_write = *pointer_write % PAGE_SIZE;
+       channel->nb_bytes--;
 
-               /*
-                * The HW is organized in pair of channels.
-                * See which register we need to read from
-                */
-               isr = ioread8(&channel->block_regs->r.isr);
-               sr = ioread8(&channel->regs->r.sr);
+       if ((channel->nb_bytes == 0) &&
+           (waitqueue_active(&channel->queue))) {
 
-               /* In case of RS-485, change from TX to RX when finishing TX.
-                * Half-duplex.
-                */
-               if ((ipoctal->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
-                   (sr & SR_TX_EMPTY) &&
-                   (channel->nb_bytes == 0)) {
-                       iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
-                       iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr);
-                       iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
-                       ipoctal->write = 1;
+               if (channel->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
+                       *channel->board_write = 1;
                        wake_up_interruptible(&channel->queue);
                }
+       }
+}
 
-               /* RX data */
-               if ((isr && channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) {
-                       value = ioread8(&channel->regs->r.rhr);
-                       flag = TTY_NORMAL;
-
-                       /* Error: count statistics */
-                       if (sr & SR_ERROR) {
-                               iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
-
-                               if (sr & SR_OVERRUN_ERROR) {
-                                       channel->stats.overrun_err++;
-                                       /* Overrun doesn't affect the current character*/
-                                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-                               }
-                               if (sr & SR_PARITY_ERROR) {
-                                       channel->stats.parity_err++;
-                                       flag = TTY_PARITY;
-                               }
-                               if (sr & SR_FRAMING_ERROR) {
-                                       channel->stats.framing_err++;
-                                       flag = TTY_FRAME;
-                               }
-                               if (sr & SR_RECEIVED_BREAK) {
-                                       channel->stats.rcv_break++;
-                                       flag = TTY_BREAK;
-                               }
-                       }
-
-                       tty_insert_flip_char(tty, value, flag);
-               }
+static void ipoctal_irq_channel(struct ipoctal_channel *channel)
+{
+       u8 isr, sr;
+       struct tty_struct *tty;
 
-               /* TX of each character */
-               if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) {
-                       unsigned int *pointer_write = &channel->pointer_write;
-
-                       if (channel->nb_bytes <= 0) {
-                               channel->nb_bytes = 0;
-                               continue;
-                       }
-
-                       value = channel->tty_port.xmit_buf[*pointer_write];
-                       iowrite8(value, &channel->regs->w.thr);
-                       channel->stats.tx++;
-                       channel->count_wr++;
-                       (*pointer_write)++;
-                       *pointer_write = *pointer_write % PAGE_SIZE;
-                       channel->nb_bytes--;
-
-                       if ((channel->nb_bytes == 0) &&
-                           (waitqueue_active(&channel->queue))) {
-
-                               if (ipoctal->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) {
-                                       ipoctal->write = 1;
-                                       wake_up_interruptible(&channel->queue);
-                               }
-                       }
-               }
+       /* If there is no client, skip the check */
+       if (!atomic_read(&channel->open))
+               return;
 
-               tty_flip_buffer_push(tty);
-               tty_kref_put(tty);
+       tty = tty_port_tty_get(&channel->tty_port);
+       if (!tty)
+               return;
+       /* The HW is organized in pair of channels.  See which register we need
+        * to read from */
+       isr = ioread8(&channel->block_regs->r.isr);
+       sr = ioread8(&channel->regs->r.sr);
+
+       /* In case of RS-485, change from TX to RX when finishing TX.
+        * Half-duplex. */
+       if ((channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) &&
+           (sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) {
+               iowrite8(CR_DISABLE_TX, &channel->regs->w.cr);
+               iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr);
+               iowrite8(CR_ENABLE_RX, &channel->regs->w.cr);
+               *channel->board_write = 1;
+               wake_up_interruptible(&channel->queue);
        }
+
+       /* RX data */
+       if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY))
+               ipoctal_irq_rx(channel, tty, sr);
+
+       /* TX of each character */
+       if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY))
+               ipoctal_irq_tx(channel);
+
+       tty_flip_buffer_push(tty);
+       tty_kref_put(tty);
+}
+
+static irqreturn_t ipoctal_irq_handler(void *arg)
+{
+       unsigned int i;
+       struct ipoctal *ipoctal = (struct ipoctal *) arg;
+
+       /* Check all channels */
+       for (i = 0; i < NR_CHANNELS; i++)
+               ipoctal_irq_channel(&ipoctal->channel[i]);
+
        return IRQ_HANDLED;
 }
 
@@ -405,8 +411,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
 
        /* Fill struct tty_driver with ipoctal data */
        tty->owner = THIS_MODULE;
-       tty->driver_name = "ipoctal";
-       sprintf(name, "ipoctal.%d.%d.", bus_nr, slot);
+       tty->driver_name = KBUILD_MODNAME;
+       sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot);
        tty->name = name;
        tty->major = 0;
 
@@ -431,6 +437,8 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
        ipoctal->tty_drv = tty;
 
        for (i = 0; i < NR_CHANNELS; i++) {
+               struct device *tty_dev;
+
                channel = &ipoctal->channel[i];
                tty_port_init(&channel->tty_port);
                tty_port_alloc_xmit_buf(&channel->tty_port);
@@ -444,7 +452,11 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr,
                channel->pointer_read = 0;
                channel->pointer_write = 0;
                channel->nb_bytes = 0;
-               tty_register_device(tty, i, NULL);
+               tty_dev = tty_register_device(tty, i, NULL);
+               if (IS_ERR(tty_dev)) {
+                       dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n");
+                       continue;
+               }
 
                /*
                 * Enable again the RX. TX will be enabled when
@@ -487,9 +499,11 @@ static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel,
        return i;
 }
 
-static int ipoctal_write(struct ipoctal_channel *channel,
-                        const unsigned char *buf, int count)
+static int ipoctal_write_tty(struct tty_struct *tty,
+                            const unsigned char *buf, int count)
 {
+       struct ipoctal_channel *channel = tty->driver_data;
+
        channel->nb_bytes = 0;
        channel->count_wr = 0;
 
@@ -513,14 +527,6 @@ static int ipoctal_write(struct ipoctal_channel *channel,
        return channel->count_wr;
 }
 
-static int ipoctal_write_tty(struct tty_struct *tty,
-                            const unsigned char *buf, int count)
-{
-       struct ipoctal_channel *channel = tty->driver_data;
-
-       return ipoctal_write(channel, buf, count);
-}
-
 static int ipoctal_write_room(struct tty_struct *tty)
 {
        struct ipoctal_channel *channel = tty->driver_data;
@@ -725,6 +731,7 @@ static int ipoctal_probe(struct ipack_device *dev)
        if (res)
                goto out_uninst;
 
+       dev_set_drvdata(&dev->dev, ipoctal);
        list_add_tail(&ipoctal->list, &ipoctal_list);
        return 0;
 
@@ -751,14 +758,9 @@ static void __ipoctal_remove(struct ipoctal *ipoctal)
        kfree(ipoctal);
 }
 
-static void ipoctal_remove(struct ipack_device *device)
+static void ipoctal_remove(struct ipack_device *idev)
 {
-       struct ipoctal *ipoctal, *next;
-
-       list_for_each_entry_safe(ipoctal, next, &ipoctal_list, list) {
-               if (ipoctal->dev == device)
-                       __ipoctal_remove(ipoctal);
-       }
+       __ipoctal_remove(dev_get_drvdata(&idev->dev));
 }
 
 static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = {