static void msm_i2c_interrupt_locked(void) { uint32_t status = readl(dev.pdata->i2c_base + I2C_STATUS); bool not_done = true; #if DEBUG_I2C dump_status(status); #endif if (!dev.msg) { I2C_DBG(DEBUGLEVEL, "IRQ but nothing to do!, status %x\n", status); return; } if (status & I2C_STATUS_ERROR_MASK) goto out_err; if (!(status & I2C_STATUS_WR_BUFFER_FULL)) not_done = msm_i2c_fill_write_buffer(); if (status & I2C_STATUS_RD_BUFFER_FULL) msm_i2c_read_buffer(); if (dev.pos >= 0 && dev.cnt == 0) { if (dev.rem > 1) { dev.rem--; dev.msg++; dev.pos = -1; dev.cnt = dev.msg->len; } else if (!not_done && !dev.need_flush) { timeout = 0; return; } } return; out_err: I2C_ERR("error, status %x\n", status); dev.ret = ERROR; timeout = ERR_TIMED_OUT; }
static void msm_i2c_interrupt_locked(struct msm_i2c_dev *dev) { uint32_t status = readl(dev->base + I2C_STATUS); bool not_done = true; #if DEBUG dump_status(status); #endif if (!dev->msg) { dev_err(dev->dev, "IRQ but nothing to do!, status %x\n", status); return; } if (status & I2C_STATUS_ERROR_MASK) goto out_err; if (!(status & I2C_STATUS_WR_BUFFER_FULL)) not_done = msm_i2c_fill_write_buffer(dev); if (status & I2C_STATUS_RD_BUFFER_FULL) msm_i2c_read_buffer(dev); if (dev->pos >= 0 && dev->cnt == 0) { if (dev->rem > 1) { dev->rem--; dev->msg++; dev->pos = -1; dev->cnt = dev->msg->len; } else if (!not_done && !dev->need_flush) goto out_complete; } return; out_err: dev_err(dev->dev, "error, status %x \ (%02X,%02X,%02X)(%02X,%02X,%02X)(cnt:%d,pos:%d)\n", status, dev->msg->addr, dev->reg, dev->msg->flags, dev->last_addr, dev->last_reg, dev->last_flag, dev->cnt, dev->pos); dev->ret = -EIO; out_complete: complete(dev->complete); }