예제 #1
0
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);
}