Commit caab3147 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:
 "Three driver bugfixes for I2C. Buisness as usual"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: mediatek: Fix apdma and i2c hand-shake timeout
  i2c: i801: Fix the i2c-mux gpiod_lookup_table not being properly terminated
  i2c: sprd: use a specific timeout to avoid system hang up issue
parents 6bae85bd 05f6f727
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1449,7 +1449,7 @@ static int i801_add_mux(struct i801_priv *priv)

	/* Register GPIO descriptor lookup table */
	lookup = devm_kzalloc(dev,
			      struct_size(lookup, table, mux_config->n_gpios),
			      struct_size(lookup, table, mux_config->n_gpios + 1),
			      GFP_KERNEL);
	if (!lookup)
		return -ENOMEM;
+22 −5
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#define I2C_IO_CONFIG_OPEN_DRAIN	0x0003
#define I2C_IO_CONFIG_PUSH_PULL		0x0000
#define I2C_SOFT_RST			0x0001
#define I2C_HANDSHAKE_RST		0x0020
#define I2C_FIFO_ADDR_CLR		0x0001
#define I2C_DELAY_LEN			0x0002
#define I2C_TIME_CLR_VALUE		0x0000
@@ -45,6 +46,7 @@
#define I2C_WRRD_TRANAC_VALUE		0x0002
#define I2C_RD_TRANAC_VALUE		0x0001
#define I2C_SCL_MIS_COMP_VALUE		0x0000
#define I2C_CHN_CLR_FLAG		0x0000

#define I2C_DMA_CON_TX			0x0000
#define I2C_DMA_CON_RX			0x0001
@@ -54,7 +56,9 @@
#define I2C_DMA_START_EN		0x0001
#define I2C_DMA_INT_FLAG_NONE		0x0000
#define I2C_DMA_CLR_FLAG		0x0000
#define I2C_DMA_WARM_RST		0x0001
#define I2C_DMA_HARD_RST		0x0002
#define I2C_DMA_HANDSHAKE_RST		0x0004

#define MAX_SAMPLE_CNT_DIV		8
#define MAX_STEP_CNT_DIV		64
@@ -475,11 +479,24 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
{
	u16 control_reg;

	if (i2c->dev_comp->dma_sync) {
		writel(I2C_DMA_WARM_RST, i2c->pdmabase + OFFSET_RST);
		udelay(10);
		writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
		udelay(10);
		writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_HARD_RST,
		       i2c->pdmabase + OFFSET_RST);
		mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST | I2C_SOFT_RST,
			       OFFSET_SOFTRESET);
		udelay(10);
		writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
		mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET);
	} else {
		writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
		udelay(50);
		writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);

		mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET);
	}

	/* Set ioconfig */
	if (i2c->use_push_pull)
+7 −1
Original line number Diff line number Diff line
@@ -72,6 +72,8 @@

/* timeout (ms) for pm runtime autosuspend */
#define SPRD_I2C_PM_TIMEOUT	1000
/* timeout (ms) for transfer message */
#define I2C_XFER_TIMEOUT	1000

/* SPRD i2c data structure */
struct sprd_i2c {
@@ -244,6 +246,7 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap,
			       struct i2c_msg *msg, bool is_last_msg)
{
	struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
	unsigned long time_left;

	i2c_dev->msg = msg;
	i2c_dev->buf = msg->buf;
@@ -273,7 +276,10 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap,

	sprd_i2c_opt_start(i2c_dev);

	wait_for_completion(&i2c_dev->complete);
	time_left = wait_for_completion_timeout(&i2c_dev->complete,
				msecs_to_jiffies(I2C_XFER_TIMEOUT));
	if (!time_left)
		return -ETIMEDOUT;

	return i2c_dev->err;
}