mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
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
This commit is contained in:
commit
caab314792
@ -1449,7 +1449,7 @@ static int i801_add_mux(struct i801_priv *priv)
|
|||||||
|
|
||||||
/* Register GPIO descriptor lookup table */
|
/* Register GPIO descriptor lookup table */
|
||||||
lookup = devm_kzalloc(dev,
|
lookup = devm_kzalloc(dev,
|
||||||
struct_size(lookup, table, mux_config->n_gpios),
|
struct_size(lookup, table, mux_config->n_gpios + 1),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!lookup)
|
if (!lookup)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003
|
#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003
|
||||||
#define I2C_IO_CONFIG_PUSH_PULL 0x0000
|
#define I2C_IO_CONFIG_PUSH_PULL 0x0000
|
||||||
#define I2C_SOFT_RST 0x0001
|
#define I2C_SOFT_RST 0x0001
|
||||||
|
#define I2C_HANDSHAKE_RST 0x0020
|
||||||
#define I2C_FIFO_ADDR_CLR 0x0001
|
#define I2C_FIFO_ADDR_CLR 0x0001
|
||||||
#define I2C_DELAY_LEN 0x0002
|
#define I2C_DELAY_LEN 0x0002
|
||||||
#define I2C_TIME_CLR_VALUE 0x0000
|
#define I2C_TIME_CLR_VALUE 0x0000
|
||||||
@ -45,6 +46,7 @@
|
|||||||
#define I2C_WRRD_TRANAC_VALUE 0x0002
|
#define I2C_WRRD_TRANAC_VALUE 0x0002
|
||||||
#define I2C_RD_TRANAC_VALUE 0x0001
|
#define I2C_RD_TRANAC_VALUE 0x0001
|
||||||
#define I2C_SCL_MIS_COMP_VALUE 0x0000
|
#define I2C_SCL_MIS_COMP_VALUE 0x0000
|
||||||
|
#define I2C_CHN_CLR_FLAG 0x0000
|
||||||
|
|
||||||
#define I2C_DMA_CON_TX 0x0000
|
#define I2C_DMA_CON_TX 0x0000
|
||||||
#define I2C_DMA_CON_RX 0x0001
|
#define I2C_DMA_CON_RX 0x0001
|
||||||
@ -54,7 +56,9 @@
|
|||||||
#define I2C_DMA_START_EN 0x0001
|
#define I2C_DMA_START_EN 0x0001
|
||||||
#define I2C_DMA_INT_FLAG_NONE 0x0000
|
#define I2C_DMA_INT_FLAG_NONE 0x0000
|
||||||
#define I2C_DMA_CLR_FLAG 0x0000
|
#define I2C_DMA_CLR_FLAG 0x0000
|
||||||
|
#define I2C_DMA_WARM_RST 0x0001
|
||||||
#define I2C_DMA_HARD_RST 0x0002
|
#define I2C_DMA_HARD_RST 0x0002
|
||||||
|
#define I2C_DMA_HANDSHAKE_RST 0x0004
|
||||||
|
|
||||||
#define MAX_SAMPLE_CNT_DIV 8
|
#define MAX_SAMPLE_CNT_DIV 8
|
||||||
#define MAX_STEP_CNT_DIV 64
|
#define MAX_STEP_CNT_DIV 64
|
||||||
@ -475,11 +479,24 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
|
|||||||
{
|
{
|
||||||
u16 control_reg;
|
u16 control_reg;
|
||||||
|
|
||||||
writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
|
if (i2c->dev_comp->dma_sync) {
|
||||||
udelay(50);
|
writel(I2C_DMA_WARM_RST, i2c->pdmabase + OFFSET_RST);
|
||||||
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
|
udelay(10);
|
||||||
|
writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
|
||||||
mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET);
|
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 */
|
/* Set ioconfig */
|
||||||
if (i2c->use_push_pull)
|
if (i2c->use_push_pull)
|
||||||
|
@ -72,6 +72,8 @@
|
|||||||
|
|
||||||
/* timeout (ms) for pm runtime autosuspend */
|
/* timeout (ms) for pm runtime autosuspend */
|
||||||
#define SPRD_I2C_PM_TIMEOUT 1000
|
#define SPRD_I2C_PM_TIMEOUT 1000
|
||||||
|
/* timeout (ms) for transfer message */
|
||||||
|
#define I2C_XFER_TIMEOUT 1000
|
||||||
|
|
||||||
/* SPRD i2c data structure */
|
/* SPRD i2c data structure */
|
||||||
struct sprd_i2c {
|
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 i2c_msg *msg, bool is_last_msg)
|
||||||
{
|
{
|
||||||
struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
|
struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
|
||||||
|
unsigned long time_left;
|
||||||
|
|
||||||
i2c_dev->msg = msg;
|
i2c_dev->msg = msg;
|
||||||
i2c_dev->buf = msg->buf;
|
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);
|
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;
|
return i2c_dev->err;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user