linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / char / synclink_gt.c
index b4d1f4e..a0b4c66 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: synclink_gt.c,v 4.25 2006/02/06 21:20:33 paulkf Exp $
+ * $Id: synclink_gt.c,v 4.22 2006/01/09 20:16:06 paulkf Exp $
  *
  * Device driver for Microgate SyncLink GT serial adapters.
  *
@@ -92,7 +92,7 @@
  * module identification
  */
 static char *driver_name     = "SyncLink GT";
-static char *driver_version  = "$Revision: 4.25 $";
+static char *driver_version  = "$Revision: 4.22 $";
 static char *tty_driver_name = "synclink_gt";
 static char *tty_dev_prefix  = "ttySLG";
 MODULE_LICENSE("GPL");
@@ -187,20 +187,6 @@ static void hdlcdev_exit(struct slgt_info *info);
 #define SLGT_MAX_PORTS 4
 #define SLGT_REG_SIZE  256
 
-/*
- * conditional wait facility
- */
-struct cond_wait {
-       struct cond_wait *next;
-       wait_queue_head_t q;
-       wait_queue_t wait;
-       unsigned int data;
-};
-static void init_cond_wait(struct cond_wait *w, unsigned int data);
-static void add_cond_wait(struct cond_wait **head, struct cond_wait *w);
-static void remove_cond_wait(struct cond_wait **head, struct cond_wait *w);
-static void flush_cond_wait(struct cond_wait **head);
-
 /*
  * DMA buffer descriptor and access macros
  */
@@ -283,9 +269,6 @@ struct slgt_info {
        struct timer_list       tx_timer;
        struct timer_list       rx_timer;
 
-       unsigned int            gpio_present;
-       struct cond_wait        *gpio_wait_q;
-
        spinlock_t lock;        /* spinlock for synchronizing with ISR */
 
        struct work_struct task;
@@ -391,16 +374,11 @@ static MGSL_PARAMS default_params = {
 #define DESC_LIST_SIZE 4096
 
 #define MASK_PARITY  BIT1
-#define MASK_FRAMING BIT2
-#define MASK_BREAK   BIT3
+#define MASK_FRAMING BIT0
+#define MASK_BREAK   BIT14
 #define MASK_OVERRUN BIT4
 
 #define GSR   0x00 /* global status */
-#define JCR   0x04 /* JTAG control */
-#define IODR  0x08 /* GPIO direction */
-#define IOER  0x0c /* GPIO interrupt enable */
-#define IOVR  0x10 /* GPIO value */
-#define IOSR  0x14 /* GPIO interrupt status */
 #define TDR   0x80 /* tx data */
 #define RDR   0x80 /* rx data */
 #define TCR   0x82 /* tx control */
@@ -525,9 +503,6 @@ static int  tiocmset(struct tty_struct *tty, struct file *file,
 static void set_break(struct tty_struct *tty, int break_state);
 static int  get_interface(struct slgt_info *info, int __user *if_mode);
 static int  set_interface(struct slgt_info *info, int if_mode);
-static int  set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
-static int  get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
-static int  wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
 
 /*
  * driver functions
@@ -1137,12 +1112,6 @@ static int ioctl(struct tty_struct *tty, struct file *file,
                return get_interface(info, argp);
        case MGSL_IOCSIF:
                return set_interface(info,(int)arg);
-       case MGSL_IOCSGPIO:
-               return set_gpio(info, argp);
-       case MGSL_IOCGGPIO:
-               return get_gpio(info, argp);
-       case MGSL_IOCWAITGPIO:
-               return wait_gpio(info, argp);
        case TIOCGICOUNT:
                spin_lock_irqsave(&info->lock,flags);
                cnow = info->icount;
@@ -1396,7 +1365,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
        }
 
        info->params.encoding = new_encoding;
-       info->params.crc_type = new_crctype;
+       info->params.crc_type = new_crctype;;
 
        /* if network interface up, reprogram hardware */
        if (info->netcount)
@@ -1793,22 +1762,26 @@ static void rx_async(struct slgt_info *info)
                DBGDATA(info, p, count, "rx");
 
                for(i=0 ; i < count; i+=2, p+=2) {
+                       if (tty && chars) {
+                               tty_flip_buffer_push(tty);
+                               chars = 0;
+                       }
                        ch = *p;
                        icount->rx++;
 
                        stat = 0;
 
-                       if ((status = *(p+1) & (BIT9 + BIT8))) {
-                               if (status & BIT9)
+                       if ((status = *(p+1) & (BIT1 + BIT0))) {
+                               if (status & BIT1)
                                        icount->parity++;
-                               else if (status & BIT8)
+                               else if (status & BIT0)
                                        icount->frame++;
                                /* discard char if tty control flags say so */
                                if (status & info->ignore_status_mask)
                                        continue;
-                               if (status & BIT9)
+                               if (status & BIT1)
                                        stat = TTY_PARITY;
-                               else if (status & BIT8)
+                               else if (status & BIT0)
                                        stat = TTY_FRAME;
                        }
                        if (tty) {
@@ -2185,24 +2158,6 @@ static void isr_txeom(struct slgt_info *info, unsigned short status)
        }
 }
 
-static void isr_gpio(struct slgt_info *info, unsigned int changed, unsigned int state)
-{
-       struct cond_wait *w, *prev;
-
-       /* wake processes waiting for specific transitions */
-       for (w = info->gpio_wait_q, prev = NULL ; w != NULL ; w = w->next) {
-               if (w->data & changed) {
-                       w->data = state;
-                       wake_up_interruptible(&w->q);
-                       if (prev != NULL)
-                               prev->next = w->next;
-                       else
-                               info->gpio_wait_q = w->next;
-               } else
-                       prev = w;
-       }
-}
-
 /* interrupt service routine
  *
  *     irq     interrupt number
@@ -2238,22 +2193,6 @@ static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                }
        }
 
-       if (info->gpio_present) {
-               unsigned int state;
-               unsigned int changed;
-               while ((changed = rd_reg32(info, IOSR)) != 0) {
-                       DBGISR(("%s iosr=%08x\n", info->device_name, changed));
-                       /* read latched state of GPIO signals */
-                       state = rd_reg32(info, IOVR);
-                       /* clear pending GPIO interrupt bits */
-                       wr_reg32(info, IOSR, changed);
-                       for (i=0 ; i < info->port_count ; i++) {
-                               if (info->port_array[i] != NULL)
-                                       isr_gpio(info->port_array[i], changed, state);
-                       }
-               }
-       }
-
        for(i=0; i < info->port_count ; i++) {
                struct slgt_info *port = info->port_array[i];
 
@@ -2337,8 +2276,6 @@ static void shutdown(struct slgt_info *info)
                set_signals(info);
        }
 
-       flush_cond_wait(&info->gpio_wait_q);
-
        spin_unlock_irqrestore(&info->lock,flags);
 
        if (info->tty)
@@ -2713,175 +2650,6 @@ static int set_interface(struct slgt_info *info, int if_mode)
        return 0;
 }
 
-/*
- * set general purpose IO pin state and direction
- *
- * user_gpio fields:
- * state   each bit indicates a pin state
- * smask   set bit indicates pin state to set
- * dir     each bit indicates a pin direction (0=input, 1=output)
- * dmask   set bit indicates pin direction to set
- */
-static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
-{
-       unsigned long flags;
-       struct gpio_desc gpio;
-       __u32 data;
-
-       if (!info->gpio_present)
-               return -EINVAL;
-       if (copy_from_user(&gpio, user_gpio, sizeof(gpio)))
-               return -EFAULT;
-       DBGINFO(("%s set_gpio state=%08x smask=%08x dir=%08x dmask=%08x\n",
-                info->device_name, gpio.state, gpio.smask,
-                gpio.dir, gpio.dmask));
-
-       spin_lock_irqsave(&info->lock,flags);
-       if (gpio.dmask) {
-               data = rd_reg32(info, IODR);
-               data |= gpio.dmask & gpio.dir;
-               data &= ~(gpio.dmask & ~gpio.dir);
-               wr_reg32(info, IODR, data);
-       }
-       if (gpio.smask) {
-               data = rd_reg32(info, IOVR);
-               data |= gpio.smask & gpio.state;
-               data &= ~(gpio.smask & ~gpio.state);
-               wr_reg32(info, IOVR, data);
-       }
-       spin_unlock_irqrestore(&info->lock,flags);
-
-       return 0;
-}
-
-/*
- * get general purpose IO pin state and direction
- */
-static int get_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
-{
-       struct gpio_desc gpio;
-       if (!info->gpio_present)
-               return -EINVAL;
-       gpio.state = rd_reg32(info, IOVR);
-       gpio.smask = 0xffffffff;
-       gpio.dir   = rd_reg32(info, IODR);
-       gpio.dmask = 0xffffffff;
-       if (copy_to_user(user_gpio, &gpio, sizeof(gpio)))
-               return -EFAULT;
-       DBGINFO(("%s get_gpio state=%08x dir=%08x\n",
-                info->device_name, gpio.state, gpio.dir));
-       return 0;
-}
-
-/*
- * conditional wait facility
- */
-static void init_cond_wait(struct cond_wait *w, unsigned int data)
-{
-       init_waitqueue_head(&w->q);
-       init_waitqueue_entry(&w->wait, current);
-       w->data = data;
-}
-
-static void add_cond_wait(struct cond_wait **head, struct cond_wait *w)
-{
-       set_current_state(TASK_INTERRUPTIBLE);
-       add_wait_queue(&w->q, &w->wait);
-       w->next = *head;
-       *head = w;
-}
-
-static void remove_cond_wait(struct cond_wait **head, struct cond_wait *cw)
-{
-       struct cond_wait *w, *prev;
-       remove_wait_queue(&cw->q, &cw->wait);
-       set_current_state(TASK_RUNNING);
-       for (w = *head, prev = NULL ; w != NULL ; prev = w, w = w->next) {
-               if (w == cw) {
-                       if (prev != NULL)
-                               prev->next = w->next;
-                       else
-                               *head = w->next;
-                       break;
-               }
-       }
-}
-
-static void flush_cond_wait(struct cond_wait **head)
-{
-       while (*head != NULL) {
-               wake_up_interruptible(&(*head)->q);
-               *head = (*head)->next;
-       }
-}
-
-/*
- * wait for general purpose I/O pin(s) to enter specified state
- *
- * user_gpio fields:
- * state - bit indicates target pin state
- * smask - set bit indicates watched pin
- *
- * The wait ends when at least one watched pin enters the specified
- * state. When 0 (no error) is returned, user_gpio->state is set to the
- * state of all GPIO pins when the wait ends.
- *
- * Note: Each pin may be a dedicated input, dedicated output, or
- * configurable input/output. The number and configuration of pins
- * varies with the specific adapter model. Only input pins (dedicated
- * or configured) can be monitored with this function.
- */
-static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio)
-{
-       unsigned long flags;
-       int rc = 0;
-       struct gpio_desc gpio;
-       struct cond_wait wait;
-       u32 state;
-
-       if (!info->gpio_present)
-               return -EINVAL;
-       if (copy_from_user(&gpio, user_gpio, sizeof(gpio)))
-               return -EFAULT;
-       DBGINFO(("%s wait_gpio() state=%08x smask=%08x\n",
-                info->device_name, gpio.state, gpio.smask));
-       /* ignore output pins identified by set IODR bit */
-       if ((gpio.smask &= ~rd_reg32(info, IODR)) == 0)
-               return -EINVAL;
-       init_cond_wait(&wait, gpio.smask);
-
-       spin_lock_irqsave(&info->lock, flags);
-       /* enable interrupts for watched pins */
-       wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask);
-       /* get current pin states */
-       state = rd_reg32(info, IOVR);
-
-       if (gpio.smask & ~(state ^ gpio.state)) {
-               /* already in target state */
-               gpio.state = state;
-       } else {
-               /* wait for target state */
-               add_cond_wait(&info->gpio_wait_q, &wait);
-               spin_unlock_irqrestore(&info->lock, flags);
-               schedule();
-               if (signal_pending(current))
-                       rc = -ERESTARTSYS;
-               else
-                       gpio.state = wait.data;
-               spin_lock_irqsave(&info->lock, flags);
-               remove_cond_wait(&info->gpio_wait_q, &wait);
-       }
-
-       /* disable all GPIO interrupts if no waiting processes */
-       if (info->gpio_wait_q == NULL)
-               wr_reg32(info, IOER, 0);
-       spin_unlock_irqrestore(&info->lock,flags);
-
-       if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio)))
-               rc = -EFAULT;
-       return rc;
-}
-
 static int modem_input_wait(struct slgt_info *info,int arg)
 {
        unsigned long flags;
@@ -3398,10 +3166,8 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
                } else {
                        port_array[0]->irq_requested = 1;
                        adapter_test(port_array[0]);
-                       for (i=1 ; i < port_count ; i++) {
+                       for (i=1 ; i < port_count ; i++)
                                port_array[i]->init_error = port_array[0]->init_error;
-                               port_array[i]->gpio_present = port_array[0]->gpio_present;
-                       }
                }
        }
 }
@@ -4535,7 +4301,7 @@ static int register_test(struct slgt_info *info)
                        break;
                }
        }
-       info->gpio_present = (rd_reg32(info, JCR) & BIT5) ? 1 : 0;
+
        info->init_error = rc ? 0 : DiagStatus_AddressFailure;
        return rc;
 }