i2c: aspeed: Adjust spinlock scope in the irq handler
authorJae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
Mon, 2 Jul 2018 21:40:11 +0000 (14:40 -0700)
committerWolfram Sang <wsa@the-dreams.de>
Fri, 20 Jul 2018 22:23:42 +0000 (00:23 +0200)
This patch adjusts spinlock scope to make it wrap the whole irq
handler using a single lock/unlock which covers both master and
slave handlers.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
drivers/i2c/busses/i2c-aspeed.c

index e056a316289f8479b166fb18e672f076a726c5f2..efb89422d496dfe638a1a47d0495c7c2ba0fe8e5 100644 (file)
@@ -234,7 +234,6 @@ static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
        bool irq_handled = true;
        u8 value;
 
-       spin_lock(&bus->lock);
        if (!slave) {
                irq_handled = false;
                goto out;
@@ -325,7 +324,6 @@ static bool aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus)
        writel(status_ack, bus->base + ASPEED_I2C_INTR_STS_REG);
 
 out:
-       spin_unlock(&bus->lock);
        return irq_handled;
 }
 #endif /* CONFIG_I2C_SLAVE */
@@ -389,7 +387,6 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)
        u8 recv_byte;
        int ret;
 
-       spin_lock(&bus->lock);
        irq_status = readl(bus->base + ASPEED_I2C_INTR_STS_REG);
        /* Ack all interrupt bits. */
        writel(irq_status, bus->base + ASPEED_I2C_INTR_STS_REG);
@@ -547,22 +544,29 @@ out_no_complete:
                dev_err(bus->dev,
                        "irq handled != irq. expected 0x%08x, but was 0x%08x\n",
                        irq_status, status_ack);
-       spin_unlock(&bus->lock);
        return !!irq_status;
 }
 
 static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
 {
        struct aspeed_i2c_bus *bus = dev_id;
+       bool ret;
+
+       spin_lock(&bus->lock);
 
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
        if (aspeed_i2c_slave_irq(bus)) {
                dev_dbg(bus->dev, "irq handled by slave.\n");
-               return IRQ_HANDLED;
+               ret = true;
+               goto out;
        }
 #endif /* CONFIG_I2C_SLAVE */
 
-       return aspeed_i2c_master_irq(bus) ? IRQ_HANDLED : IRQ_NONE;
+       ret = aspeed_i2c_master_irq(bus);
+
+out:
+       spin_unlock(&bus->lock);
+       return ret ? IRQ_HANDLED : IRQ_NONE;
 }
 
 static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,