vserver 1.9.5.x5
[linux-2.6.git] / drivers / i2c / busses / i2c-ite.c
index da926a6..6263811 100644 (file)
@@ -62,6 +62,7 @@ static int own;
 static struct iic_ite gpi;
 static wait_queue_head_t iic_wait;
 static int iic_pending;
+static spinlock_t lock;
 
 /* ----- local functions ----------------------------------------------        */
 
@@ -108,6 +109,7 @@ static int iic_ite_getclock(void *data)
 static void iic_ite_waitforpin(void) {
 
    int timeout = 2;
+   long flags;
 
    /* If interrupts are enabled (which they are), then put the process to
     * sleep.  This process will be awakened by two events -- either the
@@ -116,24 +118,36 @@ static void iic_ite_waitforpin(void) {
     * of time and return.
     */
    if (gpi.iic_irq > 0) {
-       cli();
+       spin_lock_irqsave(&lock, flags);
        if (iic_pending == 0) {
-               interruptible_sleep_on_timeout(&iic_wait, timeout*HZ );
-       } else
+               spin_unlock_irqrestore(&lock, flags);
+               if (interruptible_sleep_on_timeout(&iic_wait, timeout*HZ)) {
+                       spin_lock_irqsave(&lock, flags);
+                       if (iic_pending == 1) {
+                               iic_pending = 0;
+                       }
+                       spin_unlock_irqrestore(&lock, flags);
+               }
+       } else {
                iic_pending = 0;
-       sti();
+               spin_unlock_irqrestore(&lock, flags);
+       }
    } else {
       udelay(100);
    }
 }
 
 
-static void iic_ite_handler(int this_irq, void *dev_id, struct pt_regs *regs) 
+static irqreturn_t iic_ite_handler(int this_irq, void *dev_id,
+                                                       struct pt_regs *regs)
 {
-       
-   iic_pending = 1;
+       spin_lock(&lock);
+       iic_pending = 1;
+       spin_unlock(&lock);
+
+       wake_up_interruptible(&iic_wait);
 
-   wake_up_interruptible(&iic_wait);
+       return IRQ_HANDLED;
 }
 
 
@@ -221,6 +235,7 @@ static int __init iic_ite_init(void)
 
        iic_ite_data.data = (void *)piic;
        init_waitqueue_head(&iic_wait);
+       spin_lock_init(&lock);
        if (iic_hw_resrc_init() == 0) {
                if (i2c_iic_add_bus(&iic_ite_ops) < 0)
                        return -ENODEV;