summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-05-14 04:19:22 +0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-05-14 04:19:22 +0400
commit8b6ee04067310a6397476f05f06e52dabd8b0bb6 (patch)
tree022a153b777a9e38f49d46e4fb8f1e6747d4a5f4 /drivers/i2c
parentb48d441a8ab8a89bd32a3a981a05b8a26905dfc7 (diff)
parent7c0482e3d055e5de056d3c693b821e39205b99ae (diff)
downloadlinux-8b6ee04067310a6397476f05f06e52dabd8b0bb6.tar.xz
Merge branch 'merge' into next
We want the irq fixes from the "merge" branch.
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-eg20t.c4
-rw-r--r--drivers/i2c/busses/i2c-mxs.c8
-rw-r--r--drivers/i2c/busses/i2c-pnx.c3
-rw-r--r--drivers/i2c/busses/i2c-tegra.c8
4 files changed, 15 insertions, 8 deletions
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
index f086131cb1c7..c811289b61e2 100644
--- a/drivers/i2c/busses/i2c-eg20t.c
+++ b/drivers/i2c/busses/i2c-eg20t.c
@@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
{
long ret;
ret = wait_event_timeout(pch_event,
- (adap->pch_event_flag != 0), msecs_to_jiffies(50));
+ (adap->pch_event_flag != 0), msecs_to_jiffies(1000));
if (ret == 0) {
pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
@@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit);
MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C");
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.lapis-semi.com>");
+MODULE_AUTHOR("Tomoya MORINAGA. <tomoya.rohm@gmail.com>");
module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
module_param(pch_clk, int, (S_IRUSR | S_IWUSR));
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 3d471d56bf15..76b8af44f634 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -227,6 +227,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
return -EINVAL;
init_completion(&i2c->cmd_complete);
+ i2c->cmd_err = 0;
flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
@@ -252,6 +253,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
if (i2c->cmd_err == -ENXIO)
mxs_i2c_reset(i2c);
+ else
+ writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
+ i2c->regs + MXS_I2C_QUEUECTRL_CLR);
dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);
@@ -299,8 +303,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ))
/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
i2c->cmd_err = -EIO;
- else
- i2c->cmd_err = 0;
is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
@@ -384,8 +386,6 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
if (ret)
return -EBUSY;
- writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
- i2c->regs + MXS_I2C_QUEUECTRL_CLR);
writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
platform_set_drvdata(pdev, NULL);
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 04be9f82e14b..eb8ad538c79f 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -546,8 +546,7 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev,
{
struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
- /* FIXME: shouldn't this be clk_disable? */
- clk_enable(alg_data->clk);
+ clk_disable(alg_data->clk);
return 0;
}
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index e978635e60f0..55e5ea62ccee 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -516,6 +516,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
return 0;
+ /*
+ * NACK interrupt is generated before the I2C controller generates the
+ * STOP condition on the bus. So wait for 2 clock periods before resetting
+ * the controller so that STOP condition has been delivered properly.
+ */
+ if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
+ udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
+
tegra_i2c_init(i2c_dev);
if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
if (msg->flags & I2C_M_IGNORE_NAK)