From: Youngmin Nam Date: Tue, 5 Jan 2016 06:18:28 +0000 (+0900) Subject: i2c: exynos5: add conditional reset of hsi2c master before transfer X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=2a5e8467ef6745eb25796d4bb826406de161edd0;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git i2c: exynos5: add conditional reset of hsi2c master before transfer This patch resets hsi2c master before transfer if related property was set. HSI2C master can goes into master arbitration lost state if there is the fluctuation on SCL/SDA line before starting transfer. To getting out of this state, mater should be reset. Change-Id: I2487152abff708f61182bbca866f51a421a0c4c9 Signed-off-by: Youngmin Nam --- diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index 4378ecdc8dc0..56cd86c16a33 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -816,6 +816,16 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap, exynos_update_ip_idle_status(i2c->idle_ip_index, 0); clk_prepare_enable(i2c->clk); #endif + + /* If master is in arbitration lost state before transfer */ + /* master should be reset */ + if (i2c->reset_before_trans) { + if (unlikely((readl(i2c->regs + HSI2C_TRANS_STATUS) + & HSI2C_MAST_ST_MASK) == 0xC)) { + i2c->need_hw_init = 1; + } + } + if (i2c->need_hw_init) exynos5_i2c_reset(i2c); @@ -959,6 +969,11 @@ static int exynos5_i2c_probe(struct platform_device *pdev) else i2c->stop_after_trans = 0; + if (of_get_property(np, "samsung,reset-before-trans", NULL)) + i2c->reset_before_trans = 1; + else + i2c->reset_before_trans = 0; + i2c->idle_ip_index = exynos_get_idle_ip_index(dev_name(&pdev->dev)); strlcpy(i2c->adap.name, "exynos5-i2c", sizeof(i2c->adap.name)); diff --git a/drivers/i2c/busses/i2c-exynos5.h b/drivers/i2c/busses/i2c-exynos5.h index 70a6bcb15185..cf299da1838f 100644 --- a/drivers/i2c/busses/i2c-exynos5.h +++ b/drivers/i2c/busses/i2c-exynos5.h @@ -54,5 +54,6 @@ struct exynos5_i2c { unsigned int transfer_delay; int idle_ip_index; + int reset_before_trans; }; #endif /*__I2C_EXYNOS5_H */