From a1ee06b72968d80ab9362ec61143c4f090cc2d1b Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Thu, 21 Jan 2010 18:55:32 +0100 Subject: i2c: mxc: let time to generate stop bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After generating the stop bit by changing MSTA from 1 to 0, the i2c_imx->stopped was immediatly set to 1. The second test on i2c_imx->stopped then is correct and the controller never waits if the bus is busy. This patch corrects this. On mx31moboard, stop bit was not generated on single write transfers. This was kept unnoticed as other transfers are made afterwards that help the write recipient to resynchronize. Thanks to Philippe and Michael for the debugging. Signed-off-by: Valentin Longchamp Signed-off by: Philippe Rétornaz Reported-by: Michael Bonani Acked-by; Wolfram Sang Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-imx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/i2c/busses/i2c-imx.c') diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index e3654d683e15..602b30e32cf3 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -226,7 +226,6 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) temp = readb(i2c_imx->base + IMX_I2C_I2CR); temp &= ~(I2CR_MSTA | I2CR_MTX); writeb(temp, i2c_imx->base + IMX_I2C_I2CR); - i2c_imx->stopped = 1; } if (cpu_is_mx1()) { /* @@ -236,8 +235,10 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) udelay(i2c_imx->disable_delay); } - if (!i2c_imx->stopped) + if (!i2c_imx->stopped) { i2c_imx_bus_busy(i2c_imx, 0); + i2c_imx->stopped = 1; + } /* Disable I2C controller */ writeb(0, i2c_imx->base + IMX_I2C_I2CR); -- cgit v1.2.1 From 4927fbf11dc1057cd9c94dd40358e5f98c999311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 8 Jan 2010 17:23:17 +0100 Subject: i2c: imx: call ioremap only after request_mem_region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit accordingly adapt order of release_mem_region and release_mem_region on remove. Signed-off-by: Uwe Kleine-König Cc: Ben Dooks Cc: Wolfram Sang Cc: Richard Zhao Cc: Darius Augulis Cc: Sascha Hauer Cc: linux-i2c@vger.kernel.org Acked-by: Wolfram Sang Signed-off-by: Ben Dooks --- drivers/i2c/busses/i2c-imx.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers/i2c/busses/i2c-imx.c') diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 602b30e32cf3..75bf820e7ccb 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -497,22 +497,23 @@ static int __init i2c_imx_probe(struct platform_device *pdev) } res_size = resource_size(res); + + if (!request_mem_region(res->start, res_size, DRIVER_NAME)) { + ret = -EBUSY; + goto fail0; + } + base = ioremap(res->start, res_size); if (!base) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -EIO; - goto fail0; + goto fail1; } i2c_imx = kzalloc(sizeof(struct imx_i2c_struct), GFP_KERNEL); if (!i2c_imx) { dev_err(&pdev->dev, "can't allocate interface\n"); ret = -ENOMEM; - goto fail1; - } - - if (!request_mem_region(res->start, res_size, DRIVER_NAME)) { - ret = -EBUSY; goto fail2; } @@ -583,11 +584,11 @@ fail5: fail4: clk_put(i2c_imx->clk); fail3: - release_mem_region(i2c_imx->res->start, resource_size(res)); -fail2: kfree(i2c_imx); -fail1: +fail2: iounmap(base); +fail1: + release_mem_region(res->start, resource_size(res)); fail0: if (pdata && pdata->exit) pdata->exit(&pdev->dev); @@ -619,8 +620,8 @@ static int __exit i2c_imx_remove(struct platform_device *pdev) clk_put(i2c_imx->clk); - release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res)); iounmap(i2c_imx->base); + release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res)); kfree(i2c_imx); return 0; } -- cgit v1.2.1