Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f313b43b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fix from Wolfram Sang:
 "A single driver bugfix for I2C.

  The bug was found by systematically stress testing the driver, so I am
  confident to merge it that late in the cycle although it is probably
  unusually large"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: xlp9xx: Fix case where SSIF read transaction completes early
parents 112cbae2 5eb173f5
Loading
Loading
Loading
Loading
+28 −13
Original line number Diff line number Diff line
@@ -191,28 +191,43 @@ static void xlp9xx_i2c_drain_rx_fifo(struct xlp9xx_i2c_dev *priv)
	if (priv->len_recv) {
		/* read length byte */
		rlen = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);

		/*
		 * We expect at least 2 interrupts for I2C_M_RECV_LEN
		 * transactions. The length is updated during the first
		 * interrupt, and the buffer contents are only copied
		 * during subsequent interrupts. If in case the interrupts
		 * get merged we would complete the transaction without
		 * copying out the bytes from RX fifo. To avoid this now we
		 * drain the fifo as and when data is available.
		 * We drained the rlen byte already, decrement total length
		 * by one.
		 */

		len--;
		if (rlen > I2C_SMBUS_BLOCK_MAX || rlen == 0) {
			rlen = 0;	/*abort transfer */
			priv->msg_buf_remaining = 0;
			priv->msg_len = 0;
		} else {
			xlp9xx_i2c_update_rlen(priv);
			return;
		}

		*buf++ = rlen;
		if (priv->client_pec)
			++rlen; /* account for error check byte */
		/* update remaining bytes and message length */
		priv->msg_buf_remaining = rlen;
		priv->msg_len = rlen + 1;
		}
		xlp9xx_i2c_update_rlen(priv);
		priv->len_recv = false;
	} else {
	}

	len = min(priv->msg_buf_remaining, len);
	for (i = 0; i < len; i++, buf++)
		*buf = xlp9xx_read_i2c_reg(priv, XLP9XX_I2C_MRXFIFO);

	priv->msg_buf_remaining -= len;
	}

	priv->msg_buf = buf;

	if (priv->msg_buf_remaining)