static int npcm_i2c_master_xfer()

in busses/i2c-npcm7xx.c [2041:2182]


static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
				int num)
{
	struct npcm_i2c *bus = container_of(adap, struct npcm_i2c, adap);
	struct i2c_msg *msg0, *msg1;
	unsigned long time_left, flags;
	u16 nwrite, nread;
	u8 *write_data, *read_data;
	u8 slave_addr;
	int timeout;
	int ret = 0;
	bool read_block = false;
	bool read_PEC = false;
	u8 bus_busy;
	unsigned long timeout_usec;

	if (bus->state == I2C_DISABLE) {
		dev_err(bus->dev, "I2C%d module is disabled", bus->num);
		return -EINVAL;
	}

	msg0 = &msgs[0];
	slave_addr = msg0->addr;
	if (msg0->flags & I2C_M_RD) { /* read */
		nwrite = 0;
		write_data = NULL;
		read_data = msg0->buf;
		if (msg0->flags & I2C_M_RECV_LEN) {
			nread = 1;
			read_block = true;
			if (msg0->flags & I2C_CLIENT_PEC)
				read_PEC = true;
		} else {
			nread = msg0->len;
		}
	} else { /* write */
		nwrite = msg0->len;
		write_data = msg0->buf;
		nread = 0;
		read_data = NULL;
		if (num == 2) {
			msg1 = &msgs[1];
			read_data = msg1->buf;
			if (msg1->flags & I2C_M_RECV_LEN) {
				nread = 1;
				read_block = true;
				if (msg1->flags & I2C_CLIENT_PEC)
					read_PEC = true;
			} else {
				nread = msg1->len;
				read_block = false;
			}
		}
	}

	/*
	 * Adaptive TimeOut: estimated time in usec + 100% margin:
	 * 2: double the timeout for clock stretching case
	 * 9: bits per transaction (including the ack/nack)
	 */
	timeout_usec = (2 * 9 * USEC_PER_SEC / bus->bus_freq) * (2 + nread + nwrite);
	timeout = max(msecs_to_jiffies(35), usecs_to_jiffies(timeout_usec));
	if (nwrite >= 32 * 1024 || nread >= 32 * 1024) {
		dev_err(bus->dev, "i2c%d buffer too big\n", bus->num);
		return -EINVAL;
	}

	time_left = jiffies + msecs_to_jiffies(DEFAULT_STALL_COUNT) + 1;
	do {
		/*
		 * we must clear slave address immediately when the bus is not
		 * busy, so we spinlock it, but we don't keep the lock for the
		 * entire while since it is too long.
		 */
		spin_lock_irqsave(&bus->lock, flags);
		bus_busy = ioread8(bus->reg + NPCM_I2CCST) & NPCM_I2CCST_BB;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
		if (!bus_busy && bus->slave)
			iowrite8((bus->slave->addr & 0x7F),
				 bus->reg + NPCM_I2CADDR1);
#endif
		spin_unlock_irqrestore(&bus->lock, flags);

	} while (time_is_after_jiffies(time_left) && bus_busy);

	if (bus_busy) {
		iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST);
		npcm_i2c_reset(bus);
		i2c_recover_bus(adap);
		return -EAGAIN;
	}

	npcm_i2c_init_params(bus);
	bus->dest_addr = slave_addr;
	bus->msgs = msgs;
	bus->msgs_num = num;
	bus->cmd_err = 0;
	bus->read_block_use = read_block;

	reinit_completion(&bus->cmd_complete);
	if (!npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread,
					write_data, read_data, read_PEC,
					read_block))
		ret = -EBUSY;

	if (ret != -EBUSY) {
		time_left = wait_for_completion_timeout(&bus->cmd_complete,
							timeout);

		if (time_left == 0) {
			if (bus->timeout_cnt < ULLONG_MAX)
				bus->timeout_cnt++;
			if (bus->master_or_slave == I2C_MASTER) {
				i2c_recover_bus(adap);
				bus->cmd_err = -EIO;
				bus->state = I2C_IDLE;
			}
		}
	}
	ret = bus->cmd_err;

	/* if there was BER, check if need to recover the bus: */
	if (bus->cmd_err == -EAGAIN)
		ret = i2c_recover_bus(adap);

	/*
	 * After any type of error, check if LAST bit is still set,
	 * due to a HW issue.
	 * It cannot be cleared without resetting the module.
	 */
	if (bus->cmd_err &&
	    (NPCM_I2CRXF_CTL_LAST_PEC & ioread8(bus->reg + NPCM_I2CRXF_CTL)))
		npcm_i2c_reset(bus);

#if IS_ENABLED(CONFIG_I2C_SLAVE)
	/* reenable slave if it was enabled */
	if (bus->slave)
		iowrite8((bus->slave->addr & 0x7F) | NPCM_I2CADDR_SAEN,
			 bus->reg + NPCM_I2CADDR1);
#endif
	return bus->cmd_err;
}