These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / i2c / busses / i2c-xiic.c
index e840004..0b20449 100644 (file)
@@ -63,6 +63,7 @@ enum xiic_endian {
  * @state:     See STATE_
  * @rx_msg:    Current RX message
  * @rx_pos:    Position within current RX message
+ * @endianness: big/little-endian byte order
  */
 struct xiic_i2c {
        void __iomem            *base;
@@ -282,7 +283,7 @@ static void xiic_reinit(struct xiic_i2c *i2c)
        /* Enable interrupts */
        xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
 
-       xiic_irq_clr_en(i2c, XIIC_INTR_AAS_MASK | XIIC_INTR_ARB_LOST_MASK);
+       xiic_irq_clr_en(i2c, XIIC_INTR_ARB_LOST_MASK);
 }
 
 static void xiic_deinit(struct xiic_i2c *i2c)
@@ -357,8 +358,9 @@ static void xiic_wakeup(struct xiic_i2c *i2c, int code)
        wake_up(&i2c->wait);
 }
 
-static void xiic_process(struct xiic_i2c *i2c)
+static irqreturn_t xiic_process(int irq, void *dev_id)
 {
+       struct xiic_i2c *i2c = dev_id;
        u32 pend, isr, ier;
        u32 clr = 0;
 
@@ -367,6 +369,7 @@ static void xiic_process(struct xiic_i2c *i2c)
         * To find which interrupts are pending; AND interrupts pending with
         * interrupts masked.
         */
+       spin_lock(&i2c->lock);
        isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
        ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
        pend = isr & ier;
@@ -377,11 +380,6 @@ static void xiic_process(struct xiic_i2c *i2c)
                __func__, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
                i2c->tx_msg, i2c->nmsgs);
 
-       /* Do not processes a devices interrupts if the device has no
-        * interrupts pending
-        */
-       if (!pend)
-               return;
 
        /* Service requesting interrupt */
        if ((pend & XIIC_INTR_ARB_LOST_MASK) ||
@@ -401,13 +399,15 @@ static void xiic_process(struct xiic_i2c *i2c)
                 */
                xiic_reinit(i2c);
 
+               if (i2c->rx_msg)
+                       xiic_wakeup(i2c, STATE_ERROR);
                if (i2c->tx_msg)
                        xiic_wakeup(i2c, STATE_ERROR);
-
-       } else if (pend & XIIC_INTR_RX_FULL_MASK) {
+       }
+       if (pend & XIIC_INTR_RX_FULL_MASK) {
                /* Receive register/FIFO is full */
 
-               clr = XIIC_INTR_RX_FULL_MASK;
+               clr |= XIIC_INTR_RX_FULL_MASK;
                if (!i2c->rx_msg) {
                        dev_dbg(i2c->adap.dev.parent,
                                "%s unexpexted RX IRQ\n", __func__);
@@ -440,9 +440,10 @@ static void xiic_process(struct xiic_i2c *i2c)
                                __xiic_start_xfer(i2c);
                        }
                }
-       } else if (pend & XIIC_INTR_BNB_MASK) {
+       }
+       if (pend & XIIC_INTR_BNB_MASK) {
                /* IIC bus has transitioned to not busy */
-               clr = XIIC_INTR_BNB_MASK;
+               clr |= XIIC_INTR_BNB_MASK;
 
                /* The bus is not busy, disable BusNotBusy interrupt */
                xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK);
@@ -455,12 +456,12 @@ static void xiic_process(struct xiic_i2c *i2c)
                        xiic_wakeup(i2c, STATE_DONE);
                else
                        xiic_wakeup(i2c, STATE_ERROR);
-
-       } else if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
+       }
+       if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) {
                /* Transmit register/FIFO is empty or ½ empty */
 
-               clr pend &
-                       (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK);
+               clr |= (pend &
+                       (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK));
 
                if (!i2c->tx_msg) {
                        dev_dbg(i2c->adap.dev.parent,
@@ -491,16 +492,13 @@ static void xiic_process(struct xiic_i2c *i2c)
                         * make sure to disable tx half
                         */
                        xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
-       } else {
-               /* got IRQ which is not acked */
-               dev_err(i2c->adap.dev.parent, "%s Got unexpected IRQ\n",
-                       __func__);
-               clr = pend;
        }
 out:
        dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr);
 
        xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr);
+       spin_unlock(&i2c->lock);
+       return IRQ_HANDLED;
 }
 
 static int xiic_bus_busy(struct xiic_i2c *i2c)
@@ -524,7 +522,7 @@ static int xiic_busy(struct xiic_i2c *i2c)
         */
        err = xiic_bus_busy(i2c);
        while (err && tries--) {
-               mdelay(1);
+               msleep(1);
                err = xiic_bus_busy(i2c);
        }
 
@@ -601,19 +599,21 @@ static void xiic_start_send(struct xiic_i2c *i2c)
 static irqreturn_t xiic_isr(int irq, void *dev_id)
 {
        struct xiic_i2c *i2c = dev_id;
-
-       spin_lock(&i2c->lock);
-       /* disable interrupts globally */
-       xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
+       u32 pend, isr, ier;
+       irqreturn_t ret = IRQ_NONE;
+       /* Do not processes a devices interrupts if the device has no
+        * interrupts pending
+        */
 
        dev_dbg(i2c->adap.dev.parent, "%s entry\n", __func__);
 
-       xiic_process(i2c);
-
-       xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
-       spin_unlock(&i2c->lock);
+       isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET);
+       ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
+       pend = isr & ier;
+       if (pend)
+               ret = IRQ_WAKE_THREAD;
 
-       return IRQ_HANDLED;
+       return ret;
 }
 
 static void __xiic_start_xfer(struct xiic_i2c *i2c)
@@ -662,16 +662,10 @@ static void __xiic_start_xfer(struct xiic_i2c *i2c)
 
 static void xiic_start_xfer(struct xiic_i2c *i2c)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&i2c->lock, flags);
+       spin_lock(&i2c->lock);
        xiic_reinit(i2c);
-       /* disable interrupts globally */
-       xiic_setreg32(i2c, XIIC_DGIER_OFFSET, 0);
-       spin_unlock_irqrestore(&i2c->lock, flags);
-
        __xiic_start_xfer(i2c);
-       xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
+       spin_unlock(&i2c->lock);
 }
 
 static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
@@ -754,7 +748,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)
        spin_lock_init(&i2c->lock);
        init_waitqueue_head(&i2c->wait);
 
-       ret = devm_request_irq(&pdev->dev, irq, xiic_isr, 0, pdev->name, i2c);
+       ret = devm_request_threaded_irq(&pdev->dev, irq, xiic_isr,
+                                       xiic_process, IRQF_ONESHOT,
+                                       pdev->name, i2c);
+
        if (ret < 0) {
                dev_err(&pdev->dev, "Cannot claim IRQ\n");
                return ret;